Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4880251
WaveFile.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
19 KB
Subscribers
None
WaveFile.cpp
View Options
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#if WIN32
#else
#include <inttypes.h>
#endif
#include "WaveFile.h"
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#define SPEAKER_RESERVED 0x80000000
#define SPEAKER_REAR_CENTER_SURROUND SPEAKER_BACK_CENTER
#define DCA_MONO 0
#define DCA_CHANNEL 1
#define DCA_STEREO 2
#define DCA_STEREO_SUMDIFF 3
#define DCA_STEREO_TOTAL 4
#define DCA_3F 5
#define DCA_2F1R 6
#define DCA_3F1R 7
#define DCA_2F2R 8
#define DCA_3F2R 9
#define DCA_4F2R 10
#define DCA_DOLBY 101
/* FIXME */
#define DCA_CHANNEL_MAX DCA_3F2R
/* We don't handle anything above that */
#define DCA_CHANNEL_BITS 6
#define DCA_CHANNEL_MASK 0x3F
#define DCA_LFE 0x80
#define DCA_ADJUST_LEVEL 0x100
#define WAVE_FORMAT_PCM 0x0001
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
static
uint8_t
wav_header
[]
=
{
'R'
,
'I'
,
'F'
,
'F'
,
0xfc
,
0xff
,
0xff
,
0xff
,
'W'
,
'A'
,
'V'
,
'E'
,
'f'
,
'm'
,
't'
,
' '
,
16
,
0
,
0
,
0
,
WAVE_FORMAT_PCM
,
WAVE_FORMAT_PCM
>>
8
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
16
,
0
,
'd'
,
'a'
,
't'
,
'a'
,
0xd8
,
0xff
,
0xff
,
0xff
};
static
uint8_t
wavmulti_header
[]
=
{
'R'
,
'I'
,
'F'
,
'F'
,
0xf0
,
0xff
,
0xff
,
0xff
,
'W'
,
'A'
,
'V'
,
'E'
,
'f'
,
'm'
,
't'
,
' '
,
40
,
0
,
0
,
0
,
(
uint8_t
)(
WAVE_FORMAT_EXTENSIBLE
&
0xFF
),
WAVE_FORMAT_EXTENSIBLE
>>
8
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
32
,
0
,
22
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
WAVE_FORMAT_IEEE_FLOAT
,
WAVE_FORMAT_IEEE_FLOAT
>>
8
,
0
,
0
,
0
,
0
,
0x10
,
0x00
,
0x80
,
0
,
0
,
0xaa
,
0
,
0x38
,
0x9b
,
0x71
,
'd'
,
'a'
,
't'
,
'a'
,
0xb4
,
0xff
,
0xff
,
0xff
};
static
void
store4
(
uint8_t
*
buf
,
int
value
)
{
buf
[
0
]
=
value
;
buf
[
1
]
=
value
>>
8
;
buf
[
2
]
=
value
>>
16
;
buf
[
3
]
=
value
>>
24
;
}
static
void
store2
(
uint8_t
*
buf
,
int
value
)
{
buf
[
0
]
=
value
;
buf
[
1
]
=
value
>>
8
;
}
static
uint32_t
find_chunk
(
FILE
*
file
,
const
uint8_t
chunk_id
[
4
])
{
uint8_t
buffer
[
8
];
while
(
1
)
{
size_t
chunksize
;
size_t
s
=
fread
(
buffer
,
1
,
8
,
file
);
if
(
s
<
8
)
return
0
;
chunksize
=
(
uint32_t
)
buffer
[
4
]
|
((
uint32_t
)
buffer
[
5
]
<<
8
)
|
((
uint32_t
)
buffer
[
6
]
<<
16
)
|
((
uint32_t
)
buffer
[
7
]
<<
24
);
if
(
!
memcmp
(
buffer
,
chunk_id
,
4
))
return
chunksize
;
fseek
(
file
,
chunksize
,
SEEK_CUR
);
}
}
CWaveFile
::
CWaveFile
(
const
char
*
Filename
,
bool
Write
)
:
Duration
(
0
),
ReadOnly
(
false
),
m_bOK
(
false
)
{
Channels
=
0
;
/* 打开文件 **/
File
=
fopen
(
Filename
,
Write
?
"wb"
:
"rb"
);
if
(
!
File
)
return
;
/* 设置写文件初始参数 **/
if
(
Write
)
{
SampleRate
=
44100
;
Channels
=
2
;
Format
=
SF_S16
;
SampleSize
=
16
;
ChannelMask
=
0
;
m_bOK
=
true
;
return
;
}
ReadOnly
=
true
;
size_t
s
;
uint8_t
buffer
[
8
];
uint8_t
*
fmt
=
NULL
;
uint32_t
v
;
uint32_t
avg_bps
;
uint32_t
block_align
;
unsigned
short
FormatType
;
unsigned
short
SampleType
;
static
const
uint8_t
riff
[
4
]
=
{
'R'
,
'I'
,
'F'
,
'F'
};
static
const
uint8_t
wave
[
4
]
=
{
'W'
,
'A'
,
'V'
,
'E'
};
static
const
uint8_t
fmt_
[
4
]
=
{
'f'
,
'm'
,
't'
,
' '
};
static
const
uint8_t
data
[
4
]
=
{
'd'
,
'a'
,
't'
,
'a'
};
/* 前四个字节为 riff **/
s
=
fread
(
buffer
,
1
,
8
,
File
);
if
(
s
<
8
)
goto
err2
;
if
(
memcmp
(
buffer
,
riff
,
4
))
goto
err2
;
/* 8~12为wave **/
/* TODO: check size (in buffer[4..8]) */
s
=
fread
(
buffer
,
1
,
4
,
File
);
if
(
s
<
4
)
goto
err2
;
if
(
memcmp
(
buffer
,
wave
,
4
))
goto
err2
;
s
=
find_chunk
(
File
,
fmt_
);
if
(
s
!=
16
&&
s
!=
18
&&
s
!=
40
)
goto
err2
;
fmt
=
(
uint8_t
*
)
malloc
(
s
);
if
(
!
fmt
)
goto
err2
;
if
(
fread
(
fmt
,
1
,
s
,
File
)
!=
s
)
goto
err3
;
/* wFormatTag */
v
=
(
uint32_t
)
fmt
[
0
]
|
((
uint32_t
)
fmt
[
1
]
<<
8
);
if
(
v
!=
WAVE_FORMAT_PCM
&&
v
!=
WAVE_FORMAT_IEEE_FLOAT
&&
v
!=
WAVE_FORMAT_EXTENSIBLE
)
goto
err3
;
FormatType
=
v
;
if
(
s
==
40
&&
0xfffe
==
v
)
{
// fmt begins at 0x14 of the wave file
v
=
*
(
unsigned
short
*
)
&
fmt
[
0x2C
-
0x14
];
}
SampleType
=
v
;
/* wChannels */
v
=
(
uint32_t
)
fmt
[
2
]
|
((
uint32_t
)
fmt
[
3
]
<<
8
);
Channels
=
v
;
if
(
v
<
1
||
v
>
32
)
goto
err3
;
/* dwSamplesPerSec */
SampleRate
=
(
uint32_t
)
fmt
[
4
]
|
((
uint32_t
)
fmt
[
5
]
<<
8
)
|
((
uint32_t
)
fmt
[
6
]
<<
16
)
|
((
uint32_t
)
fmt
[
7
]
<<
24
);
/* dwAvgBytesPerSec */
avg_bps
=
(
uint32_t
)
fmt
[
8
]
|
((
uint32_t
)
fmt
[
9
]
<<
8
)
|
((
uint32_t
)
fmt
[
10
]
<<
16
)
|
((
uint32_t
)
fmt
[
11
]
<<
24
);
/* wBlockAlign */
block_align
=
(
uint32_t
)
fmt
[
12
]
|
((
uint32_t
)
fmt
[
13
]
<<
8
);
/* wBitsPerSample */
SampleSize
=
(
uint32_t
)
fmt
[
14
]
|
((
uint32_t
)
fmt
[
15
]
<<
8
);
if
(
SampleSize
!=
8
&&
SampleSize
!=
16
&&
SampleSize
!=
32
&&
SampleSize
!=
24
&&
SampleSize
!=
64
)
goto
err3
;
switch
(
SampleSize
)
{
case
8
:
Format
=
SF_U8
;
break
;
case
16
:
Format
=
SF_S16
;
break
;
case
24
:
Format
=
SF_S24
;
break
;
case
32
:
{
if
(
SampleType
==
WAVE_FORMAT_IEEE_FLOAT
)
Format
=
SF_IEEE_FLOAT
;
else
Format
=
SF_S32
;
}
break
;
case
64
:
if
(
SampleType
!=
WAVE_FORMAT_IEEE_FLOAT
)
goto
err3
;
Format
=
SF_IEEE_DOUBLE
;
break
;
}
// Handle 24-bit samples individually
#if 0
if (SampleSize == 24 && Channels <= 2)
{
int ba24 = Channels * (SampleSize / 8); // Align to 4x
ba24 = (ba24 + 3) / 4 * 4;
if (block_align != ba24)
goto err3;
}
else
#endif
{
if
(
block_align
!=
Channels
*
(
SampleSize
/
8
))
goto
err3
;
}
if
(
avg_bps
!=
block_align
*
SampleRate
)
goto
err3
;
v
=
find_chunk
(
File
,
data
);
if
(
v
==
0
||
v
%
block_align
!=
0
)
goto
err3
;
TotalFrames
=
v
/
block_align
;
FramesRead
=
0
;
if
(
FormatType
==
WAVE_FORMAT_EXTENSIBLE
)
{
ChannelMask
=
*
(
unsigned
int
*
)(
&
fmt
[
0x14
]);
}
else
{
ChannelMask
=
0
;
}
FrameStartPos
=
ftell
(
File
);
free
(
fmt
);
m_bOK
=
true
;
return
;
err3:
free
(
fmt
);
err2:
fclose
(
File
);
File
=
NULL
;
}
bool
CWaveFile
::
GetStatus
()
{
return
m_bOK
;
}
SAMPLE_FORMAT
CWaveFile
::
GetFormat
()
{
return
Format
;
}
int
CWaveFile
::
GetTotalFrames
()
{
return
TotalFrames
;
}
int
CWaveFile
::
GetFramesRead
()
{
return
FramesRead
;
}
CWaveFile
::~
CWaveFile
()
{
if
(
File
!=
NULL
)
{
if
(
!
ReadOnly
)
{
unsigned
int
Size
=
ftell
(
File
)
-
FrameStartPos
;
// 44;
fseek
(
File
,
FrameStartPos
-
4
,
SEEK_SET
);
fwrite
(
&
Size
,
4
,
1
,
File
);
Size
+=
FrameStartPos
-
8
;
fseek
(
File
,
4
,
SEEK_SET
);
fwrite
(
&
Size
,
4
,
1
,
File
);
}
fclose
(
File
);
}
}
int
CWaveFile
::
GetSampleRate
()
{
return
SampleRate
;
}
void
CWaveFile
::
SetSampleRate
(
int
SampleRate
)
{
this
->
SampleRate
=
SampleRate
;
}
void
CWaveFile
::
SetupDone
()
{
unsigned
char
Header
[
68
];
fseek
(
File
,
0
,
SEEK_SET
);
SampleSize
=
Format
&
0xFF
;
if
(
ChannelMask
)
{
memcpy
(
Header
,
wavmulti_header
,
sizeof
(
wavmulti_header
));
if
(
Format
<
SF_IEEE_FLOAT
)
{
// store2(Header + 20, WAVE_FORMAT_PCM);
store2
(
Header
+
44
,
WAVE_FORMAT_PCM
);
}
store2
(
Header
+
22
,
Channels
);
store4
(
Header
+
24
,
SampleRate
);
store4
(
Header
+
28
,
SampleSize
/
8
*
SampleRate
*
Channels
);
store2
(
Header
+
32
,
SampleSize
/
8
*
Channels
);
store2
(
Header
+
34
,
SampleSize
/
8
*
8
);
store2
(
Header
+
38
,
SampleSize
/
8
*
8
);
store4
(
Header
+
40
,
ChannelMask
);
fwrite
(
Header
,
sizeof
(
wavmulti_header
),
1
,
File
);
}
else
{
memcpy
(
Header
,
wav_header
,
sizeof
(
wav_header
));
if
(
Format
>=
SF_IEEE_FLOAT
)
{
store2
(
Header
+
20
,
WAVE_FORMAT_IEEE_FLOAT
);
}
store2
(
Header
+
22
,
Channels
);
store4
(
Header
+
24
,
SampleRate
);
store4
(
Header
+
28
,
SampleSize
/
8
*
SampleRate
*
Channels
);
store2
(
Header
+
32
,
SampleSize
/
8
*
Channels
);
store2
(
Header
+
34
,
SampleSize
/
8
*
8
);
fwrite
(
Header
,
sizeof
(
wav_header
),
1
,
File
);
}
FrameStartPos
=
ftell
(
File
);
}
void
CWaveFile
::
Seek
(
int
FramePos
,
int
Where
)
{
// Ignoring Where
fseek
(
File
,
FrameStartPos
+
FramePos
*
Channels
*
(
SampleSize
/
8
),
Where
);
FramesRead
=
FramePos
;
}
int
CWaveFile
::
GetChannels
()
{
return
Channels
;
}
void
CWaveFile
::
SetChannels
(
int
Channels
)
{
this
->
Channels
=
Channels
;
}
void
CWaveFile
::
SetSampleFormat
(
SAMPLE_FORMAT
Format
)
{
this
->
Format
=
Format
;
}
uint32_t
CWaveFile
::
GetChannelMask
()
{
return
ChannelMask
;
}
void
CWaveFile
::
SetChannelMask
(
uint32_t
Mask
)
{
ChannelMask
=
Mask
;
}
bool
CWaveFile
::
ReadFrameAsS16
(
short
*
FrameSamples
,
int
Frames
)
{
if
(
FramesRead
>=
TotalFrames
)
return
false
;
FramesRead
+=
Frames
;
switch
(
Format
)
{
case
SF_U8:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
short
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
1
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
DirectSample
-
128
)
<<
8
;
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S16:
return
Frames
==
fread
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
);
case
SF_S24:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
unsigned
int
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
3
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
short
)(
unsigned
short
)(
DirectSample
>>
8
);
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S32:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
unsigned
int
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
4
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
short
)(
unsigned
short
)(
DirectSample
>>
16
);
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_IEEE_FLOAT:
{
float
DirectSamples
[
32
];
if
(
Frames
==
fread
(
DirectSamples
,
sizeof
(
DirectSamples
[
0
])
*
Channels
,
Frames
,
File
))
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
short
)(
DirectSamples
[
ch
+
frame
*
Channels
]
*
32768
);
}
}
return
true
;
}
return
false
;
}
case
SF_IEEE_DOUBLE:
{
double
DirectSamples
[
32
];
if
(
Frames
==
fread
(
DirectSamples
,
sizeof
(
DirectSamples
[
0
])
*
Channels
,
Frames
,
File
))
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
short
)(
DirectSamples
[
ch
+
frame
*
Channels
]
*
32768
);
}
}
return
true
;
}
return
false
;
}
}
return
false
;
}
bool
CWaveFile
::
ReadFrameAsfloat
(
float
*
FrameSamples
,
int
Frames
)
{
if
(
FramesRead
>=
TotalFrames
)
return
false
;
FramesRead
+=
Frames
;
switch
(
Format
)
{
case
SF_U8:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
short
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
1
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
DirectSample
-
128
)
/
128.0
;
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S16:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
short
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
2
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
DirectSample
/
32768.0
;
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S24:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
uint32_t
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
3
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
((
int32_t
)((
uint32_t
)(
DirectSample
<<
8
)))
/
(
double
)(((
uint32_t
)(
1
<<
31
)));
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S32:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
uint32_t
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
4
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
((
int32_t
)((
uint32_t
)(
DirectSample
)))
/
(
double
)(((
uint32_t
)(
1
<<
31
)));
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_IEEE_FLOAT:
{
if
(
fread
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
))
{
return
true
;
}
return
false
;
// float DirectSamples[32];
//
// if (Frames == fread(DirectSamples, sizeof(DirectSamples[0]) * Channels, Frames, File))
// {
// for (int frame = 0; frame < Frames; frame++)
// {
// for (int ch = 0; ch < Channels; ch++)
// {
// FrameSamples[ch + frame*Channels] = (double)(DirectSamples[ch + frame*Channels]);
// }
// }
// return true;
// }
// return false;
}
case
SF_IEEE_DOUBLE:
{
if
(
Frames
==
fread
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
))
{
return
true
;
}
return
false
;
}
}
return
false
;
}
bool
CWaveFile
::
ReadFrameAsDouble
(
double
*
FrameSamples
,
int
Frames
)
{
if
(
FramesRead
>=
TotalFrames
)
return
false
;
FramesRead
+=
Frames
;
switch
(
Format
)
{
case
SF_U8:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
short
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
1
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
DirectSample
-
128
)
/
128.0
;
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S16:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
short
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
2
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
DirectSample
/
32768.0
;
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S24:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
uint32_t
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
3
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
((
int32_t
)((
uint32_t
)(
DirectSample
<<
8
)))
/
(
double
)(((
uint32_t
)(
1
<<
31
)));
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_S32:
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
uint32_t
DirectSample
=
0
;
if
(
1
==
fread
(
&
DirectSample
,
4
,
1
,
File
))
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
((
int32_t
)((
uint32_t
)(
DirectSample
)))
/
(
double
)(((
uint32_t
)(
1
<<
31
)));
// (short)(DirectSample * 32767.0 / ((1 << 24) - 1));
}
else
{
return
false
;
}
}
}
return
true
;
}
case
SF_IEEE_FLOAT:
{
float
DirectSamples
[
32
];
if
(
Frames
==
fread
(
DirectSamples
,
sizeof
(
DirectSamples
[
0
])
*
Channels
,
Frames
,
File
))
{
for
(
int
frame
=
0
;
frame
<
Frames
;
frame
++
)
{
for
(
int
ch
=
0
;
ch
<
Channels
;
ch
++
)
{
FrameSamples
[
ch
+
frame
*
Channels
]
=
(
double
)(
DirectSamples
[
ch
+
frame
*
Channels
]);
}
}
return
true
;
}
return
false
;
}
case
SF_IEEE_DOUBLE:
{
if
(
Frames
==
fread
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
))
{
return
true
;
}
return
false
;
}
}
return
false
;
}
void
CWaveFile
::
WriteRaw
(
void
*
Raw
,
int
Size
)
{
fwrite
(
Raw
,
Size
,
1
,
File
);
}
void
CWaveFile
::
WriteFrame
(
uint8_t
*
FrameSamples
,
int
Frames
)
{
fwrite
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
);
}
void
CWaveFile
::
WriteFrame
(
short
*
FrameSamples
,
int
Frames
)
{
fwrite
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
);
}
void
CWaveFile
::
WriteFrame
(
int32_t
*
FrameSamples
,
int
Frames
)
{
fwrite
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
);
}
void
CWaveFile
::
WriteFrameS24
(
int32_t
*
FrameSamples
,
int
Frames
)
{
for
(
int
c
=
0
;
c
<
Channels
;
c
++
)
{
fwrite
(
&
FrameSamples
[
c
],
3
,
1
,
File
);
}
}
void
CWaveFile
::
WriteFrame
(
double
*
FrameSamples
,
int
Frames
)
{
fwrite
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
);
}
void
CWaveFile
::
WriteFrame
(
float
*
FrameSamples
,
int
Frames
)
{
fwrite
(
FrameSamples
,
sizeof
(
FrameSamples
[
0
])
*
Channels
,
Frames
,
File
);
}
double
CWaveFile
::
GetDuration
()
{
return
Duration
;
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Jan 12, 01:52 (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1347128
Default Alt Text
WaveFile.cpp (19 KB)
Attached To
R350 av_svc
Event Timeline
Log In to Comment