summaryrefslogtreecommitdiff
path: root/src/audio
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-10-15 17:16:49 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-10-15 17:16:49 +0300
commitc3795ba3779ec79a94ad298fc5e72b6edfc4b4e7 (patch)
tree6e57868dafad0bf25d20c5cc6c72f4d8a145dd46 /src/audio
parentb073e4c6aad0a4c35ea89c4592d5b48a39bb61f5 (diff)
Player: Streaming MP3 playback
Feed more MPEG input bitstream as it comes in.
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/player.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/src/audio/player.c b/src/audio/player.c
index ef238378..13c8c58b 100644
--- a/src/audio/player.c
+++ b/src/audio/player.c
@@ -239,36 +239,54 @@ enum iDecoderStatus decodeMpeg_Decoder_(iDecoder *d) {
239#if defined (LAGRANGE_ENABLE_MPG123) 239#if defined (LAGRANGE_ENABLE_MPG123)
240 const iBlock *input = &d->input->data; 240 const iBlock *input = &d->input->data;
241 if (!d->mpeg) { 241 if (!d->mpeg) {
242 d->inputPos = 0;
242 d->mpeg = mpg123_new(NULL, NULL); 243 d->mpeg = mpg123_new(NULL, NULL);
243 mpg123_format_none(d->mpeg); 244 mpg123_format_none(d->mpeg);
244 mpg123_format(d->mpeg, d->outputFreq, d->output.numChannels, MPG123_ENC_SIGNED_16); 245 mpg123_format(d->mpeg, d->outputFreq, d->output.numChannels, MPG123_ENC_SIGNED_16);
245 mpg123_open_feed(d->mpeg); 246 mpg123_open_feed(d->mpeg);
247 }
248 /* Feed more input. */ {
246 lock_Mutex(&d->input->mtx); 249 lock_Mutex(&d->input->mtx);
247 mpg123_feed(d->mpeg, constData_Block(input), size_Block(input)); 250 if (d->input->isComplete) {
251 d->totalInputSize = size_Block(input);
252 }
253 if (d->inputPos < size_Block(input)) {
254 mpg123_feed(d->mpeg, constData_Block(input) + d->inputPos, size_Block(input) - d->inputPos);
255 if (d->inputPos == 0) {
256 long r; int ch, enc;
257 mpg123_getformat(d->mpeg, &r, &ch, &enc);
258 iAssert(r == d->outputFreq);
259 iAssert(ch == d->output.numChannels);
260 iAssert(enc == MPG123_ENC_SIGNED_16);
261 }
262 d->inputPos = size_Block(input);
263 }
248 unlock_Mutex(&d->input->mtx); 264 unlock_Mutex(&d->input->mtx);
249 long r; int ch, enc;
250 mpg123_getformat(d->mpeg, &r, &ch, &enc);
251 iAssert(r == d->outputFreq);
252 iAssert(ch == d->output.numChannels);
253 iAssert(enc == MPG123_ENC_SIGNED_16);
254 } 265 }
255 while (size_Array(&d->pendingOutput) < d->output.count) { 266 while (size_Array(&d->pendingOutput) < d->output.count) {
256 int16_t buffer[512]; 267 int16_t buffer[512];
257 size_t bytesWritten = 0; 268 size_t bytesRead = 0;
258 const int rc = mpg123_read(d->mpeg, buffer, sizeof(buffer), &bytesWritten); 269 const int rc = mpg123_read(d->mpeg, buffer, sizeof(buffer), &bytesRead);
259 const float gain = d->gain; 270 const float gain = d->gain;
260 for (size_t i = 0; i < bytesWritten / 2; i++) { 271 for (size_t i = 0; i < bytesRead / 2; i++) {
261 buffer[i] *= gain; 272 buffer[i] *= gain;
262 } 273 }
263 pushBackN_Array(&d->pendingOutput, buffer, bytesWritten / 2 / d->output.numChannels); 274 pushBackN_Array(&d->pendingOutput, buffer, bytesRead / 2 / d->output.numChannels);
264 if (rc == MPG123_NEED_MORE) { 275 if (rc == MPG123_NEED_MORE) {
265 status = needMoreInput_DecoderStatus; 276 status = needMoreInput_DecoderStatus;
266 break; 277 break;
267 } 278 }
268 else if (rc == MPG123_DONE) { 279 else if (rc == MPG123_DONE || bytesRead == 0) {
269 break; 280 break;
270 } 281 }
271 } 282 }
283 /* Check if we know the total length already. This info should be available eventually. */
284 if (d->totalSamples == 0) {
285 const off_t off = mpg123_length(d->mpeg);
286 if (off != MPG123_ERR) {
287 d->totalSamples = off;
288 }
289 }
272 writePending_Decoder_(d); 290 writePending_Decoder_(d);
273#endif 291#endif
274 return status; 292 return status;
@@ -286,20 +304,18 @@ static iThreadResult run_Decoder_(iThread *thread) {
286 if (!d->type) break; 304 if (!d->type) break;
287 /* Have data to work on and a place to save output? */ 305 /* Have data to work on and a place to save output? */
288 enum iDecoderStatus status = ok_DecoderStatus; 306 enum iDecoderStatus status = ok_DecoderStatus;
289 if (!isEmpty_Range(&inputRange)) { 307 switch (d->type) {
290 switch (d->type) { 308 case wav_DecoderType:
291 case wav_DecoderType: 309 status = decodeWav_Decoder_(d, inputRange);
292 status = decodeWav_Decoder_(d, inputRange); 310 break;
293 break; 311 case vorbis_DecoderType:
294 case vorbis_DecoderType: 312 status = decodeVorbis_Decoder_(d);
295 status = decodeVorbis_Decoder_(d); 313 break;
296 break; 314 case mpeg_DecoderType:
297 case mpeg_DecoderType: 315 status = decodeMpeg_Decoder_(d);
298 status = decodeMpeg_Decoder_(d); 316 break;
299 break; 317 default:
300 default: 318 break;
301 break;
302 }
303 } 319 }
304 if (status == needMoreInput_DecoderStatus) { 320 if (status == needMoreInput_DecoderStatus) {
305 lock_Mutex(&d->input->mtx); 321 lock_Mutex(&d->input->mtx);
@@ -326,13 +342,13 @@ void init_Decoder(iDecoder *d, iInputBuf *input, const iContentSpec *spec) {
326 d->inputFormat = spec->inputFormat; 342 d->inputFormat = spec->inputFormat;
327 d->totalInputSize = spec->totalInputSize; 343 d->totalInputSize = spec->totalInputSize;
328 d->outputFreq = spec->output.freq; 344 d->outputFreq = spec->output.freq;
345 d->currentSample = 0;
346 d->totalSamples = spec->totalSamples;
329 init_Array(&d->pendingOutput, spec->output.channels * SDL_AUDIO_BITSIZE(spec->output.format) / 8); 347 init_Array(&d->pendingOutput, spec->output.channels * SDL_AUDIO_BITSIZE(spec->output.format) / 8);
330 init_SampleBuf(&d->output, 348 init_SampleBuf(&d->output,
331 spec->output.format, 349 spec->output.format,
332 spec->output.channels, 350 spec->output.channels,
333 spec->output.samples * 2); 351 spec->output.samples * 2);
334 d->currentSample = 0;
335 d->totalSamples = spec->totalSamples;
336 d->vorbis = NULL; 352 d->vorbis = NULL;
337#if defined (LAGRANGE_ENABLE_MPG123) 353#if defined (LAGRANGE_ENABLE_MPG123)
338 d->mpeg = NULL; 354 d->mpeg = NULL;
@@ -514,9 +530,9 @@ static iContentSpec contentSpec_Player_(const iPlayer *d) {
514 mpg123_handle *mh = mpg123_new(NULL, NULL); 530 mpg123_handle *mh = mpg123_new(NULL, NULL);
515 mpg123_open_feed(mh); 531 mpg123_open_feed(mh);
516 mpg123_feed(mh, constData_Block(&d->data->data), size_Block(&d->data->data)); 532 mpg123_feed(mh, constData_Block(&d->data->data), size_Block(&d->data->data));
517 long rate = 0; 533 long rate = 0;
518 int channels = 0; 534 int channels = 0;
519 int encoding = 0; 535 int encoding = 0;
520 if (mpg123_getformat(mh, &rate, &channels, &encoding) == MPG123_OK) { 536 if (mpg123_getformat(mh, &rate, &channels, &encoding) == MPG123_OK) {
521 content.output.freq = rate; 537 content.output.freq = rate;
522 content.output.channels = channels; 538 content.output.channels = channels;