summaryrefslogtreecommitdiffhomepage
path: root/src/audio.c
diff options
context:
space:
mode:
authorRay <[email protected]>2018-10-31 17:04:24 +0100
committerRay <[email protected]>2018-10-31 17:04:24 +0100
commitf7667aad8dd03c1cdaa2033f7a37815b7dd1f9b4 (patch)
tree17157dd791825643d69a5cfea34b9b91993988a3 /src/audio.c
parentb051f7778f42cf6b2a3285e01524549c15b41f4e (diff)
downloadraylib-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.c44
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)