summaryrefslogtreecommitdiff
path: root/src/audio
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-10-07 12:31:31 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-10-07 12:31:31 +0300
commit1ffd161fa550d5334df7ee1aaa16bc369a1324b4 (patch)
treef2ccf418fc73e34852e7eee9ece330a31c547b74 /src/audio
parent403d8fc06fda157b134f96328f98b9305509b5a3 (diff)
Drawing an audio player UI
Diffstat (limited to 'src/audio')
-rw-r--r--src/audio/player.c29
-rw-r--r--src/audio/player.h3
2 files changed, 29 insertions, 3 deletions
diff --git a/src/audio/player.c b/src/audio/player.c
index 177613bb..2d6767ea 100644
--- a/src/audio/player.c
+++ b/src/audio/player.c
@@ -146,6 +146,7 @@ iDeclareType(ContentSpec)
146struct Impl_ContentSpec { 146struct Impl_ContentSpec {
147 SDL_AudioFormat inputFormat; 147 SDL_AudioFormat inputFormat;
148 SDL_AudioSpec output; 148 SDL_AudioSpec output;
149 uint64_t totalSamples;
149 iRanges wavData; 150 iRanges wavData;
150}; 151};
151 152
@@ -168,6 +169,8 @@ struct Impl_Decoder {
168 size_t inputPos; 169 size_t inputPos;
169 iSampleBuf output; 170 iSampleBuf output;
170 iMutex outputMutex; 171 iMutex outputMutex;
172 uint64_t currentSample;
173 uint64_t totalSamples; /* zero if unknown */
171 iRanges wavData; 174 iRanges wavData;
172}; 175};
173 176
@@ -252,6 +255,7 @@ static enum iDecoderParseStatus parseWav_Decoder_(iDecoder *d, iRanges inputRang
252 } 255 }
253 } 256 }
254 iGuardMutex(&d->outputMutex, write_SampleBuf(&d->output, samples, n)); 257 iGuardMutex(&d->outputMutex, write_SampleBuf(&d->output, samples, n));
258 d->currentSample += n;
255 free(samples); 259 free(samples);
256 return ok_DecoderParseStatus; 260 return ok_DecoderParseStatus;
257} 261}
@@ -305,6 +309,8 @@ void init_Decoder(iDecoder *d, iInputBuf *input, const iContentSpec *spec) {
305 spec->output.format, 309 spec->output.format,
306 spec->output.channels, 310 spec->output.channels,
307 spec->output.samples * 2); 311 spec->output.samples * 2);
312 d->currentSample = 0;
313 d->totalSamples = spec->totalSamples;
308 init_Mutex(&d->outputMutex); 314 init_Mutex(&d->outputMutex);
309 d->thread = new_Thread(run_Decoder_); 315 d->thread = new_Thread(run_Decoder_);
310 setUserData_Thread(d->thread, d); 316 setUserData_Thread(d->thread, d);
@@ -366,6 +372,7 @@ static iContentSpec contentSpec_Player_(const iPlayer *d) {
366 return content; 372 return content;
367 } 373 }
368 /* Read all the chunks. */ 374 /* Read all the chunks. */
375 int16_t blockAlign = 0;
369 while (!atEnd_Buffer(buf)) { 376 while (!atEnd_Buffer(buf)) {
370 readData_Buffer(buf, 4, magic); 377 readData_Buffer(buf, 4, magic);
371 const size_t size = read32_Stream(is); 378 const size_t size = read32_Stream(is);
@@ -381,7 +388,7 @@ static iContentSpec contentSpec_Player_(const iPlayer *d) {
381 const int16_t numChannels = read16_Stream(is); 388 const int16_t numChannels = read16_Stream(is);
382 const int32_t freq = read32_Stream(is); 389 const int32_t freq = read32_Stream(is);
383 const uint32_t bytesPerSecond = readU32_Stream(is); 390 const uint32_t bytesPerSecond = readU32_Stream(is);
384 const int16_t blockAlign = read16_Stream(is); 391 blockAlign = read16_Stream(is);
385 const int16_t bitsPerSample = read16_Stream(is); 392 const int16_t bitsPerSample = read16_Stream(is);
386 const uint16_t extSize = (size == 18 ? readU16_Stream(is) : 0); 393 const uint16_t extSize = (size == 18 ? readU16_Stream(is) : 0);
387 iUnused(bytesPerSecond); 394 iUnused(bytesPerSecond);
@@ -418,7 +425,8 @@ static iContentSpec contentSpec_Player_(const iPlayer *d) {
418 } 425 }
419 } 426 }
420 else if (memcmp(magic, "data", 4) == 0) { 427 else if (memcmp(magic, "data", 4) == 0) {
421 content.wavData = (iRanges){ pos_Stream(is), pos_Stream(is) + size }; 428 content.wavData = (iRanges){ pos_Stream(is), pos_Stream(is) + size };
429 content.totalSamples = (uint64_t) size_Range(&content.wavData) / blockAlign;
422 break; 430 break;
423 } 431 }
424 else { 432 else {
@@ -465,11 +473,16 @@ iBool isStarted_Player(const iPlayer *d) {
465 return d->device != 0; 473 return d->device != 0;
466} 474}
467 475
468void setFormatHint_Player(iPlayer *d, const char *hint) { 476iBool isPaused_Player(const iPlayer *d) {
477 if (!d->device) return iTrue;
478 return SDL_GetAudioDeviceStatus(d->device) == SDL_AUDIO_PAUSED;
479}
469 480
481void setFormatHint_Player(iPlayer *d, const char *hint) {
470} 482}
471 483
472void updateSourceData_Player(iPlayer *d, const iBlock *data, enum iPlayerUpdate update) { 484void updateSourceData_Player(iPlayer *d, const iBlock *data, enum iPlayerUpdate update) {
485 /* TODO: Add MIME as argument */
473 iInputBuf *input = d->data; 486 iInputBuf *input = d->data;
474 lock_Mutex(&input->mtx); 487 lock_Mutex(&input->mtx);
475 switch (update) { 488 switch (update) {
@@ -527,3 +540,13 @@ void stop_Player(iPlayer *d) {
527 d->decoder = NULL; 540 d->decoder = NULL;
528 } 541 }
529} 542}
543
544float time_Player(const iPlayer *d) {
545 if (!d->decoder) return 0;
546 return (float) ((double) d->decoder->currentSample / (double) d->spec.freq);
547}
548
549float duration_Player(const iPlayer *d) {
550 if (!d->decoder) return 0;
551 return (float) ((double) d->decoder->totalSamples / (double) d->spec.freq);
552}
diff --git a/src/audio/player.h b/src/audio/player.h
index 2138c556..5c17ef6c 100644
--- a/src/audio/player.h
+++ b/src/audio/player.h
@@ -41,3 +41,6 @@ void setPaused_Player (iPlayer *, iBool isPaused);
41void stop_Player (iPlayer *); 41void stop_Player (iPlayer *);
42 42
43iBool isStarted_Player (const iPlayer *); 43iBool isStarted_Player (const iPlayer *);
44iBool isPaused_Player (const iPlayer *);
45float time_Player (const iPlayer *);
46float duration_Player (const iPlayer *);