1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// |
2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// |
3 | #include "BsFLACDecoder.h" |
4 | #include "FileSystem/BsDataStream.h" |
5 | |
6 | namespace bs |
7 | { |
8 | FLAC__StreamDecoderReadStatus streamRead(const FLAC__StreamDecoder*, FLAC__byte buffer[], size_t* bytes, void* clientData) |
9 | { |
10 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
11 | |
12 | INT64 count = (INT64)data->stream->read(buffer, *bytes); |
13 | if (count > 0) |
14 | { |
15 | *bytes = (size_t)count; |
16 | return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; |
17 | } |
18 | |
19 | if (count == 0) |
20 | return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; |
21 | |
22 | return FLAC__STREAM_DECODER_READ_STATUS_ABORT; |
23 | } |
24 | |
25 | FLAC__StreamDecoderSeekStatus streamSeek(const FLAC__StreamDecoder*, FLAC__uint64 absoluteByteOffset, void* clientData) |
26 | { |
27 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
28 | |
29 | data->stream->seek(data->streamOffset + (UINT32)absoluteByteOffset); |
30 | INT64 position = (INT64)(data->stream->tell() - data->streamOffset); |
31 | if (position >= 0) |
32 | return FLAC__STREAM_DECODER_SEEK_STATUS_OK; |
33 | else |
34 | return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; |
35 | } |
36 | |
37 | FLAC__StreamDecoderTellStatus streamTell(const FLAC__StreamDecoder*, FLAC__uint64* absoluteByteOffset, void* clientData) |
38 | { |
39 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
40 | |
41 | INT64 position = (INT64)(data->stream->tell() - data->streamOffset); |
42 | if (position >= 0) |
43 | { |
44 | *absoluteByteOffset = position; |
45 | return FLAC__STREAM_DECODER_TELL_STATUS_OK; |
46 | } |
47 | else |
48 | { |
49 | return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; |
50 | } |
51 | } |
52 | |
53 | FLAC__StreamDecoderLengthStatus streamLength(const FLAC__StreamDecoder*, FLAC__uint64* streamLength, void* clientData) |
54 | { |
55 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
56 | |
57 | *streamLength = data->stream->size() - data->streamOffset; |
58 | return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; |
59 | } |
60 | |
61 | FLAC__bool streamEof(const FLAC__StreamDecoder*, void* clientData) |
62 | { |
63 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
64 | |
65 | return data->stream->eof(); |
66 | } |
67 | |
68 | FLAC__StreamDecoderWriteStatus streamWrite(const FLAC__StreamDecoder*, const FLAC__Frame* frame, const FLAC__int32* const buffer[], void* clientData) |
69 | { |
70 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
71 | |
72 | if (!data->output) // Seek |
73 | return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; |
74 | |
75 | UINT32 bytesPerSample = data->info.bitDepth / 8; |
76 | |
77 | // If we received more data than we need, store it in the overflow buffer |
78 | UINT32 frameSamples = frame->header.blocksize * frame->header.channels; |
79 | if (data->samplesToRead < frameSamples) |
80 | { |
81 | UINT32 = frameSamples - data->samplesToRead; |
82 | UINT32 = numExtraSamples * bytesPerSample; |
83 | data->overflow.reserve(extraBytes); |
84 | } |
85 | |
86 | assert(bytesPerSample <= 4); |
87 | for (UINT32 i = 0; i < frame->header.blocksize; i++) |
88 | { |
89 | for (UINT32 j = 0; j < frame->header.channels; j++) |
90 | { |
91 | if (data->samplesToRead > 0) |
92 | { |
93 | memcpy(data->output, &buffer[j][i], bytesPerSample); |
94 | |
95 | data->output += bytesPerSample; |
96 | data->samplesToRead--; |
97 | } |
98 | else |
99 | { |
100 | UINT8 sample[4]; |
101 | memcpy(sample, &buffer[j][i], bytesPerSample); |
102 | |
103 | for(UINT32 k = 0; k < bytesPerSample; k++) |
104 | data->overflow.push_back(sample[k]); |
105 | } |
106 | } |
107 | } |
108 | |
109 | return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; |
110 | } |
111 | |
112 | void streamMetadata(const FLAC__StreamDecoder*, const FLAC__StreamMetadata* meta, void* clientData) |
113 | { |
114 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
115 | |
116 | if (meta->type == FLAC__METADATA_TYPE_STREAMINFO) |
117 | { |
118 | data->info.numSamples = (UINT32)meta->data.stream_info.total_samples * meta->data.stream_info.channels; |
119 | data->info.sampleRate = meta->data.stream_info.sample_rate; |
120 | data->info.numChannels = meta->data.stream_info.channels; |
121 | data->info.bitDepth = meta->data.stream_info.bits_per_sample; |
122 | } |
123 | } |
124 | |
125 | void streamError(const FLAC__StreamDecoder*, FLAC__StreamDecoderErrorStatus, void* clientData) |
126 | { |
127 | FLACDecoderData* data = (FLACDecoderData*)(clientData); |
128 | data->error = true; |
129 | } |
130 | |
131 | FLACDecoder::~FLACDecoder() |
132 | { |
133 | close(); |
134 | } |
135 | |
136 | bool FLACDecoder::isValid(const SPtr<DataStream>& stream, UINT32 offset) |
137 | { |
138 | stream->seek(offset); |
139 | |
140 | FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new(); |
141 | if (!decoder) |
142 | return false; |
143 | |
144 | FLACDecoderData data; |
145 | data.stream = stream; |
146 | mData.streamOffset = offset; |
147 | FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, |
148 | &streamWrite, nullptr, &streamError, &data); |
149 | |
150 | bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0; |
151 | |
152 | FLAC__stream_decoder_finish(decoder); |
153 | FLAC__stream_decoder_delete(decoder); |
154 | |
155 | return valid && !data.error; |
156 | } |
157 | |
158 | bool FLACDecoder::open(const SPtr<DataStream>& stream, AudioDataInfo& info, UINT32 offset) |
159 | { |
160 | if (stream == nullptr) |
161 | return false; |
162 | |
163 | stream->seek(offset); |
164 | |
165 | mDecoder = FLAC__stream_decoder_new(); |
166 | if (mDecoder == nullptr) |
167 | { |
168 | LOGERR("Failed to open a FLAC file." ); |
169 | return false; |
170 | } |
171 | |
172 | mData.stream = stream; |
173 | mData.streamOffset = offset; |
174 | FLAC__stream_decoder_init_stream(mDecoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, |
175 | &streamWrite, &streamMetadata, &streamError, &mData); |
176 | |
177 | if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) |
178 | { |
179 | close(); |
180 | LOGERR("Failed to open a FLAC file." ); |
181 | return false; |
182 | } |
183 | |
184 | info = mData.info; |
185 | |
186 | return true; |
187 | } |
188 | |
189 | void FLACDecoder::seek(UINT32 offset) |
190 | { |
191 | mData.output = nullptr; |
192 | mData.samplesToRead = 0; |
193 | mData.overflow.clear(); |
194 | |
195 | FLAC__stream_decoder_seek_absolute(mDecoder, offset); |
196 | } |
197 | |
198 | UINT32 FLACDecoder::read(UINT8* samples, UINT32 numSamples) |
199 | { |
200 | UINT32 overflowSize = (UINT32)mData.overflow.size(); |
201 | UINT32 overflowNumSamples = 0; |
202 | |
203 | UINT32 bytesPerSample = mData.info.bitDepth / 8; |
204 | if (overflowSize > 0) |
205 | { |
206 | UINT32 sampleSize = numSamples * bytesPerSample; |
207 | if (overflowSize > sampleSize) |
208 | { |
209 | std::copy(mData.overflow.begin(), mData.overflow.begin() + sampleSize, samples); |
210 | mData.overflow.erase(mData.overflow.begin(), mData.overflow.begin() + sampleSize); |
211 | |
212 | return numSamples; |
213 | } |
214 | else |
215 | std::copy(mData.overflow.begin(), mData.overflow.end(), samples); |
216 | |
217 | overflowNumSamples = overflowSize / bytesPerSample; |
218 | } |
219 | |
220 | mData.output = samples + overflowSize; |
221 | mData.samplesToRead = numSamples - overflowNumSamples; |
222 | mData.overflow.clear(); |
223 | |
224 | while (mData.samplesToRead > 0) |
225 | { |
226 | if (!FLAC__stream_decoder_process_single(mDecoder)) |
227 | break; |
228 | |
229 | if (FLAC__stream_decoder_get_state(mDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM) |
230 | break; |
231 | } |
232 | |
233 | return numSamples - mData.samplesToRead; |
234 | } |
235 | |
236 | void FLACDecoder::close() |
237 | { |
238 | if (mDecoder != nullptr) |
239 | { |
240 | FLAC__stream_decoder_finish(mDecoder); |
241 | FLAC__stream_decoder_delete(mDecoder); |
242 | mDecoder = nullptr; |
243 | } |
244 | } |
245 | } |
246 | |