1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/** (c) Nullsoft, Inc. C O N F I D E N T I A L
** Filename:
** Project:
** Description:
** Author: Ben Allison benski@nullsoft.com
** Created:
**/
#include "main.h"
#include "ResamplingReader.h"
ResamplingReader::ResamplingReader(Resampler *_resampler, CommonReader *_reader, size_t inputFrameSize)
: resampler(_resampler), reader(_reader),
bufferValid(0),
readState(READING)
{
bufferAlloc = inputFrameSize * 1024; // enough room for 1024 samples
buffer = (__int8 *)calloc(bufferAlloc, sizeof(__int8));
}
ResamplingReader::~ResamplingReader()
{
free(buffer);
delete resampler;
delete reader;
}
size_t ResamplingReader::ReadAudio(void *outputBuffer, size_t sizeBytes)
{
size_t origSize = sizeBytes;
__int8 *origBuffer = (__int8 *)outputBuffer;
size_t bytesResampled = 0;
read_again:
// First, read from the file decoder
switch (readState)
{
case READING:
{
size_t bytesToRead = bufferAlloc - bufferValid;
if (bytesToRead)
{
int decode_killswitch=0, decode_error;
size_t bytesRead = reader->ReadAudio(buffer + (bufferAlloc - bytesToRead), bytesToRead, &decode_killswitch, &decode_error);
bufferValid += bytesRead;
if (bytesRead == 0)
{
readState = ENDOFFILE;
}
}
}
break;
case ENDOFFILE:
resampler->Flush();
readState = FLUSHING;
}
// now, resample
size_t inputBytes = bufferValid;
size_t bytesDone;
bytesDone = resampler->Convert(buffer, &inputBytes, outputBuffer, sizeBytes);
bytesResampled += bytesDone;
// if we didn't use all of our input buffer, then we'll copy what's left to the beginning
if (inputBytes)
memmove(buffer, buffer + (bufferValid - inputBytes), inputBytes);
// mark the number of bytes of data still valid in the input buffer
bufferValid = inputBytes;
if (!bytesDone && readState == FLUSHING)
readState = DONE;
if (bytesResampled != origSize && readState != DONE) // if we didn't provide enough data to fill the output buffer
{
sizeBytes = origSize - bytesResampled;
outputBuffer = origBuffer + bytesResampled;
goto read_again;
}
return bytesResampled;
}
#define CBCLASS ResamplingReader
START_DISPATCH;
CB(IFC_AUDIOSTREAM_READAUDIO, ReadAudio)
END_DISPATCH;
|