diff options
| author | Ray <[email protected]> | 2018-10-31 17:04:24 +0100 |
|---|---|---|
| committer | Ray <[email protected]> | 2018-10-31 17:04:24 +0100 |
| commit | f7667aad8dd03c1cdaa2033f7a37815b7dd1f9b4 (patch) | |
| tree | 17157dd791825643d69a5cfea34b9b91993988a3 /src/audio.c | |
| parent | b051f7778f42cf6b2a3285e01524549c15b41f4e (diff) | |
| download | raylib-f7667aad8dd03c1cdaa2033f7a37815b7dd1f9b4.tar.gz raylib-f7667aad8dd03c1cdaa2033f7a37815b7dd1f9b4.zip | |
Reviewed audio issues
- Updated dr_mp3 and implemented it
- Reviewed sampleCount vs frameCount
- Reviewed XM playing (some weird things...)
Diffstat (limited to 'src/audio.c')
| -rw-r--r-- | src/audio.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/src/audio.c b/src/audio.c index 51023280..5ec23bb2 100644 --- a/src/audio.c +++ b/src/audio.c @@ -214,7 +214,7 @@ typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioB // Audio buffer structure // NOTE: Slightly different logic is used when feeding data to the playback device depending on whether or not data is streamed -typedef struct AudioBuffer AudioBuffer; +typedef struct AudioBuffer AudioBuffer; struct AudioBuffer { mal_dsp dsp; // Required for format conversion float volume; @@ -1130,13 +1130,12 @@ Music LoadMusicStream(const char *fileName) TraceLog(LOG_INFO, "[%s] MP3 sample rate: %i", fileName, music->ctxMp3.sampleRate); TraceLog(LOG_INFO, "[%s] MP3 bits per sample: %i", fileName, 32); TraceLog(LOG_INFO, "[%s] MP3 channels: %i", fileName, music->ctxMp3.channels); - TraceLog(LOG_INFO, "[%s] MP3 frames remaining: %i", fileName, (unsigned int)music->ctxMp3.framesRemaining); music->stream = InitAudioStream(music->ctxMp3.sampleRate, 32, music->ctxMp3.channels); // TODO: There is not an easy way to compute the total number of samples available // in an MP3, frames size could be variable... we tried with a 60 seconds music... but crashes... - music->totalSamples = 60*music->ctxMp3.sampleRate*music->ctxMp3.channels; + music->totalSamples = drmp3_get_pcm_frame_count(&music->ctxMp3)*music->ctxMp3.channels; music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_MP3; music->loopCount = -1; // Infinite loop by default @@ -1161,8 +1160,8 @@ Music LoadMusicStream(const char *fileName) music->ctxType = MUSIC_MODULE_XM; music->loopCount = -1; // Infinite loop by default - TraceLog(LOG_DEBUG, "[%s] XM number of samples: %i", fileName, music->totalSamples); - TraceLog(LOG_DEBUG, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); + TraceLog(LOG_INFO, "[%s] XM number of samples: %i", fileName, music->totalSamples); + TraceLog(LOG_INFO, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f); } else musicLoaded = false; } @@ -1283,7 +1282,7 @@ void StopMusicStream(Music music) case MUSIC_AUDIO_FLAC: /* TODO: Restart FLAC context */ break; #endif #if defined(SUPPORT_FILEFORMAT_MP3) - case MUSIC_AUDIO_MP3: /* TODO: Restart MP3 context */ break; + case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame(&music->ctxMp3, 0); break; #endif #if defined(SUPPORT_FILEFORMAT_XM) case MUSIC_MODULE_XM: /* TODO: Restart XM context */ break; @@ -1306,13 +1305,13 @@ void UpdateMusicStream(Music music) unsigned int subBufferSizeInFrames = ((AudioBuffer *)music->stream.audioBuffer)->bufferSizeInFrames/2; // NOTE: Using dynamic allocation because it could require more than 16KB - void *pcm = calloc(subBufferSizeInFrames*music->stream.sampleSize/8*music->stream.channels, 1); + void *pcm = calloc(subBufferSizeInFrames*music->stream.channels*music->stream.sampleSize/8, 1); int samplesCount = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts while (IsAudioBufferProcessed(music->stream)) { - if (music->samplesLeft >= subBufferSizeInFrames) samplesCount = subBufferSizeInFrames; + if ((music->samplesLeft/music->stream.channels) >= subBufferSizeInFrames) samplesCount = subBufferSizeInFrames*music->stream.channels; else samplesCount = music->samplesLeft; // TODO: Really don't like ctxType thingy... @@ -1321,27 +1320,31 @@ void UpdateMusicStream(Music music) case MUSIC_AUDIO_OGG: { // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) - stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels); + stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount); } break; #if defined(SUPPORT_FILEFORMAT_FLAC) case MUSIC_AUDIO_FLAC: { // NOTE: Returns the number of samples to process - unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, samplesCount*music->stream.channels, (short *)pcm); + unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, samplesCount, (short *)pcm); } break; #endif #if defined(SUPPORT_FILEFORMAT_MP3) case MUSIC_AUDIO_MP3: { - // NOTE: Returns the number of samples to process - unsigned int numSamplesMp3 = (unsigned int)drmp3_read_f32(&music->ctxMp3, samplesCount*music->stream.channels, (float *)pcm); + // NOTE: samplesCount, actually refers to framesCount and returns the number of frames processed + unsigned int numFramesMp3 = (unsigned int)drmp3_read_pcm_frames_f32(&music->ctxMp3, samplesCount/music->stream.channels, (float *)pcm); } break; #endif #if defined(SUPPORT_FILEFORMAT_XM) - case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, samplesCount); break; + case MUSIC_MODULE_XM: + { + // NOTE: Internally this function considers 2 channels generation, so samplesCount/2 --> WEIRD + jar_xm_generate_samples_16bit(music->ctxXm, (short *)pcm, samplesCount/2); + } break; #endif #if defined(SUPPORT_FILEFORMAT_MOD) case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, samplesCount, 0); break; @@ -1414,7 +1417,7 @@ void SetMusicLoopCount(Music music, int count) // Get music time length (in seconds) float GetMusicTimeLength(Music music) { - float totalSeconds = (float)music->totalSamples/music->stream.sampleRate; + float totalSeconds = (float)music->totalSamples/(music->stream.sampleRate*music->stream.channels); return totalSeconds; } @@ -1425,12 +1428,11 @@ float GetMusicTimePlayed(Music music) float secondsPlayed = 0.0f; unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; - secondsPlayed = (float)samplesPlayed/music->stream.sampleRate; + secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); return secondsPlayed; } - // Init audio stream (to stream audio pcm data) AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels) { @@ -1509,11 +1511,11 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount) unsigned char *subBuffer = audioBuffer->buffer + ((subBufferSizeInFrames*stream.channels*(stream.sampleSize/8))*subBufferToUpdate); // Does this API expect a whole buffer to be updated in one go? Assuming so, but if not will need to change this logic. - if (subBufferSizeInFrames >= (mal_uint32)samplesCount) + if (subBufferSizeInFrames >= (mal_uint32)samplesCount/stream.channels) { mal_uint32 framesToWrite = subBufferSizeInFrames; - if (framesToWrite > (mal_uint32)samplesCount) framesToWrite = (mal_uint32)samplesCount; + if (framesToWrite > ((mal_uint32)samplesCount/stream.channels)) framesToWrite = (mal_uint32)samplesCount/stream.channels; mal_uint32 bytesToWrite = framesToWrite*stream.channels*(stream.sampleSize/8); memcpy(subBuffer, data, bytesToWrite); @@ -1867,13 +1869,13 @@ static Wave LoadMP3(const char *fileName) Wave wave = { 0 }; // Decode an entire MP3 file in one go - uint64_t totalSampleCount = 0; + uint64_t totalFrameCount = 0; drmp3_config config = { 0 }; - wave.data = drmp3_open_and_decode_file_f32(fileName, &config, &totalSampleCount); + wave.data = drmp3_open_file_and_read_f32(fileName, &config, &totalFrameCount); wave.channels = config.outputChannels; wave.sampleRate = config.outputSampleRate; - wave.sampleCount = (int)totalSampleCount; + wave.sampleCount = (int)totalFrameCount*wave.channels; wave.sampleSize = 32; // NOTE: Only support up to 2 channels (mono, stereo) |
