fixed leaks, also see pbr example review required

This commit is contained in:
Chris 2019-09-15 17:35:14 +01:00
parent 65e942e5be
commit 5dd8ee76ba
4 changed files with 66 additions and 43 deletions

View File

@ -98,7 +98,17 @@ int main(void)
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
UnloadMaterial(model.materials[0]); // Unload material: shader and textures //
// REQUIRES REVIEW
// as unload model removes *just* the maps now (user may be using shaders
// and textures elsewhere) when using a custom material you need to unload
// it then give the model a default model (to avoid double free)
// how ever this still results in a small leak....
UnloadMaterial(model.materials[0]);
model.materials[0] = LoadMaterialDefault();
UnloadModel(model); // Unload model UnloadModel(model); // Unload model
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
@ -143,7 +153,7 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
mat.maps[MAP_METALNESS].texture = LoadTexture("resources/pbr/trooper_metalness.png"); mat.maps[MAP_METALNESS].texture = LoadTexture("resources/pbr/trooper_metalness.png");
mat.maps[MAP_ROUGHNESS].texture = LoadTexture("resources/pbr/trooper_roughness.png"); mat.maps[MAP_ROUGHNESS].texture = LoadTexture("resources/pbr/trooper_roughness.png");
mat.maps[MAP_OCCLUSION].texture = LoadTexture("resources/pbr/trooper_ao.png"); mat.maps[MAP_OCCLUSION].texture = LoadTexture("resources/pbr/trooper_ao.png");
// Load equirectangular to cubemap shader // Load equirectangular to cubemap shader
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
Shader shdrCubemap = LoadShader("resources/shaders/glsl330/cubemap.vs", "resources/shaders/glsl330/cubemap.fs"); Shader shdrCubemap = LoadShader("resources/shaders/glsl330/cubemap.vs", "resources/shaders/glsl330/cubemap.fs");
@ -171,7 +181,7 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
#else #else
Shader shdrBRDF = LoadShader("resources/shaders/glsl100/brdf.vs", "resources/shaders/glsl100/brdf.fs"); Shader shdrBRDF = LoadShader("resources/shaders/glsl100/brdf.vs", "resources/shaders/glsl100/brdf.fs");
#endif #endif
// Setup required shader locations // Setup required shader locations
SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT); SetShaderValue(shdrCubemap, GetShaderLocation(shdrCubemap, "equirectangularMap"), (int[1]){ 0 }, UNIFORM_INT);
SetShaderValue(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, UNIFORM_INT); SetShaderValue(shdrIrradiance, GetShaderLocation(shdrIrradiance, "environmentMap"), (int[1]){ 0 }, UNIFORM_INT);

View File

@ -669,7 +669,8 @@ Model LoadModel(const char *fileName)
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
model.materials[0] = LoadMaterialDefault(); model.materials[0] = LoadMaterialDefault();
model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); // this is a double allocation, as LoadXXX should do it....
//model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
} }
return model; return model;
@ -2797,10 +2798,11 @@ static Model LoadOBJ(const char *fileName)
{ {
model.materialCount = materialCount; model.materialCount = materialCount;
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
}
}
model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
/* /*
// Multiple meshes data reference // Multiple meshes data reference
// NOTE: They are provided as a faces offset // NOTE: They are provided as a faces offset
@ -2915,12 +2917,17 @@ static Model LoadOBJ(const char *fileName)
if (materials[m].displacement_texname != NULL) model.materials[m].maps[MAP_HEIGHT].texture = LoadTexture(materials[m].displacement_texname); //char *displacement_texname; // disp if (materials[m].displacement_texname != NULL) model.materials[m].maps[MAP_HEIGHT].texture = LoadTexture(materials[m].displacement_texname); //char *displacement_texname; // disp
} }
if (model.meshMaterial[0]==-1) {
model.meshMaterial[0] = 0; // will be given default material by LoadModel
}
tinyobj_attrib_free(&attrib); tinyobj_attrib_free(&attrib);
tinyobj_shapes_free(meshes, meshCount); tinyobj_shapes_free(meshes, meshCount);
tinyobj_materials_free(materials, materialCount); tinyobj_materials_free(materials, materialCount);
RL_FREE(data); // oh ray how did you miss this...! :-p RL_FREE(data); // oh ray how did you miss this...! :-p
} }
// NOTE: At this point we have all model data loaded // NOTE: At this point we have all model data loaded
TraceLog(LOG_INFO, "[%s] Model loaded successfully in RAM (CPU)", fileName); TraceLog(LOG_INFO, "[%s] Model loaded successfully in RAM (CPU)", fileName);
@ -3251,6 +3258,8 @@ static Model LoadIQM(const char *fileName)
} }
} }
model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
fclose(iqmFile); fclose(iqmFile);
RL_FREE(imesh); RL_FREE(imesh);
RL_FREE(tri); RL_FREE(tri);

View File

@ -198,10 +198,10 @@ typedef enum { AUDIO_BUFFER_USAGE_STATIC = 0, AUDIO_BUFFER_USAGE_STREAM } AudioB
// playback device depending on whether or not data is streamed // playback device depending on whether or not data is streamed
struct rAudioBuffer { struct rAudioBuffer {
ma_pcm_converter dsp; // PCM data converter ma_pcm_converter dsp; // PCM data converter
float volume; // Audio buffer volume float volume; // Audio buffer volume
float pitch; // Audio buffer pitch float pitch; // Audio buffer pitch
bool playing; // Audio buffer state: AUDIO_PLAYING bool playing; // Audio buffer state: AUDIO_PLAYING
bool paused; // Audio buffer state: AUDIO_PAUSED bool paused; // Audio buffer state: AUDIO_PAUSED
bool looping; // Audio buffer looping, always true for AudioStreams bool looping; // Audio buffer looping, always true for AudioStreams
@ -209,11 +209,11 @@ struct rAudioBuffer {
bool isSubBufferProcessed[2]; // SubBuffer processed (virtual double buffer) bool isSubBufferProcessed[2]; // SubBuffer processed (virtual double buffer)
unsigned int frameCursorPos; // Frame cursor position unsigned int frameCursorPos; // Frame cursor position
unsigned int bufferSizeInFrames; // Total buffer size in frames unsigned int bufferSizeInFrames; // Total buffer size in frames
unsigned int totalFramesProcessed; // Total frames processed in this buffer (required for play timming) unsigned int totalFramesProcessed; // Total frames processed in this buffer (required for play timming)
unsigned char *buffer; // Data buffer, on music stream keeps filling unsigned char *buffer; // Data buffer, on music stream keeps filling
rAudioBuffer *next; // Next audio buffer on the list rAudioBuffer *next; // Next audio buffer on the list
rAudioBuffer *prev; // Previous audio buffer on the list rAudioBuffer *prev; // Previous audio buffer on the list
}; };
@ -289,7 +289,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
if (!audioBuffer->playing || audioBuffer->paused) continue; if (!audioBuffer->playing || audioBuffer->paused) continue;
ma_uint32 framesRead = 0; ma_uint32 framesRead = 0;
while (1) while (1)
{ {
if (framesRead > frameCount) if (framesRead > frameCount)
@ -302,7 +302,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
// Just read as much data as we can from the stream // Just read as much data as we can from the stream
ma_uint32 framesToRead = (frameCount - framesRead); ma_uint32 framesToRead = (frameCount - framesRead);
while (framesToRead > 0) while (framesToRead > 0)
{ {
float tempBuffer[1024]; // 512 frames for stereo float tempBuffer[1024]; // 512 frames for stereo
@ -387,7 +387,7 @@ static ma_uint32 OnAudioBufferDSPRead(ma_pcm_converter *pDSP, void *pFramesOut,
{ {
if (framesRead >= frameCount) break; if (framesRead >= frameCount) break;
} }
else else
{ {
if (isSubBufferProcessed[currentSubBufferIndex]) break; if (isSubBufferProcessed[currentSubBufferIndex]) break;
} }
@ -465,16 +465,20 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr
static void InitAudioBufferPool() static void InitAudioBufferPool()
{ {
// Dummy buffers // Dummy buffers
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
{ {
audioBufferPool[i] = InitAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC); audioBufferPool[i] = InitAudioBuffer(DEVICE_FORMAT, DEVICE_CHANNELS, DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC);
// Not needed (only the audiobuffer header) - leak prevention!
RL_FREE(audioBufferPool[i]->buffer);
} }
} }
// Close the audio buffers pool // Close the audio buffers pool
static void CloseAudioBufferPool() static void CloseAudioBufferPool()
{ {
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) RL_FREE(audioBufferPool[i]); for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) {
RL_FREE(audioBufferPool[i]);
}
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -486,7 +490,7 @@ void InitAudioDevice(void)
// Init audio context // Init audio context
ma_context_config contextConfig = ma_context_config_init(); ma_context_config contextConfig = ma_context_config_init();
contextConfig.logCallback = OnLog; contextConfig.logCallback = OnLog;
ma_result result = ma_context_init(NULL, 0, &contextConfig, &context); ma_result result = ma_context_init(NULL, 0, &contextConfig, &context);
if (result != MA_SUCCESS) if (result != MA_SUCCESS)
{ {
@ -589,7 +593,7 @@ AudioBuffer *InitAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
{ {
AudioBuffer *audioBuffer = (AudioBuffer *)RL_CALLOC(1, sizeof(AudioBuffer)); AudioBuffer *audioBuffer = (AudioBuffer *)RL_CALLOC(1, sizeof(AudioBuffer));
audioBuffer->buffer = RL_CALLOC(bufferSizeInFrames*channels*ma_get_bytes_per_sample(format), 1); audioBuffer->buffer = RL_CALLOC(bufferSizeInFrames*channels*ma_get_bytes_per_sample(format), 1);
if (audioBuffer == NULL) if (audioBuffer == NULL)
{ {
TraceLog(LOG_ERROR, "InitAudioBuffer() : Failed to allocate memory for audio buffer"); TraceLog(LOG_ERROR, "InitAudioBuffer() : Failed to allocate memory for audio buffer");
@ -608,7 +612,7 @@ AudioBuffer *InitAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
dspConfig.onRead = OnAudioBufferDSPRead; // Callback on data reading dspConfig.onRead = OnAudioBufferDSPRead; // Callback on data reading
dspConfig.pUserData = audioBuffer; // Audio data pointer dspConfig.pUserData = audioBuffer; // Audio data pointer
dspConfig.allowDynamicSampleRate = true; // Required for pitch shifting dspConfig.allowDynamicSampleRate = true; // Required for pitch shifting
ma_result result = ma_pcm_converter_init(&dspConfig, &audioBuffer->dsp); ma_result result = ma_pcm_converter_init(&dspConfig, &audioBuffer->dsp);
if (result != MA_SUCCESS) if (result != MA_SUCCESS)
@ -655,7 +659,7 @@ void CloseAudioBuffer(AudioBuffer *buffer)
bool IsAudioBufferPlaying(AudioBuffer *buffer) bool IsAudioBufferPlaying(AudioBuffer *buffer)
{ {
bool result = false; bool result = false;
if (buffer != NULL) result = (buffer->playing && !buffer->paused); if (buffer != NULL) result = (buffer->playing && !buffer->paused);
else TraceLog(LOG_ERROR, "IsAudioBufferPlaying() : No audio buffer"); else TraceLog(LOG_ERROR, "IsAudioBufferPlaying() : No audio buffer");
@ -698,7 +702,7 @@ void StopAudioBuffer(AudioBuffer *buffer)
void PauseAudioBuffer(AudioBuffer *buffer) void PauseAudioBuffer(AudioBuffer *buffer)
{ {
if (buffer != NULL) buffer->paused = true; if (buffer != NULL) buffer->paused = true;
else TraceLog(LOG_ERROR, "PauseAudioBuffer() : No audio buffer"); else TraceLog(LOG_ERROR, "PauseAudioBuffer() : No audio buffer");
} }
// Resume an audio buffer // Resume an audio buffer
@ -722,8 +726,8 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
{ {
float pitchMul = pitch/buffer->pitch; float pitchMul = pitch/buffer->pitch;
// Pitching is just an adjustment of the sample rate. // Pitching is just an adjustment of the sample rate.
// Note that this changes the duration of the sound: // Note that this changes the duration of the sound:
// - higher pitches will make the sound faster // - higher pitches will make the sound faster
// - lower pitches make it slower // - lower pitches make it slower
ma_uint32 newOutputSampleRate = (ma_uint32)((float)buffer->dsp.src.config.sampleRateOut/pitchMul); ma_uint32 newOutputSampleRate = (ma_uint32)((float)buffer->dsp.src.config.sampleRateOut/pitchMul);
@ -816,7 +820,7 @@ Sound LoadSoundFromWave(Wave wave)
if (wave.data != NULL) if (wave.data != NULL)
{ {
// When using miniaudio we need to do our own mixing. // When using miniaudio we need to do our own mixing.
// To simplify this we need convert the format of each sound to be consistent with // To simplify this we need convert the format of each sound to be consistent with
// the format used to open the playback device. We can do this two ways: // the format used to open the playback device. We can do this two ways:
// //
@ -964,7 +968,7 @@ void PlaySoundMulti(Sound sound)
oldAge = audioBufferPoolChannels[i]; oldAge = audioBufferPoolChannels[i];
oldIndex = i; oldIndex = i;
} }
if (!IsAudioBufferPlaying(audioBufferPool[i])) if (!IsAudioBufferPlaying(audioBufferPool[i]))
{ {
index = i; index = i;
@ -976,17 +980,17 @@ void PlaySoundMulti(Sound sound)
if (index == -1) if (index == -1)
{ {
TraceLog(LOG_WARNING,"pool age %i ended a sound early no room in buffer pool", audioBufferPoolCounter); TraceLog(LOG_WARNING,"pool age %i ended a sound early no room in buffer pool", audioBufferPoolCounter);
if (oldIndex == -1) if (oldIndex == -1)
{ {
// Shouldn't be able to get here... but just in case something odd happens! // Shouldn't be able to get here... but just in case something odd happens!
TraceLog(LOG_ERROR,"sound buffer pool couldn't determine oldest buffer not playing sound"); TraceLog(LOG_ERROR,"sound buffer pool couldn't determine oldest buffer not playing sound");
return; return;
} }
index = oldIndex; index = oldIndex;
// Just in case... // Just in case...
StopAudioBuffer(audioBufferPool[index]); StopAudioBuffer(audioBufferPool[index]);
} }
@ -997,7 +1001,7 @@ void PlaySoundMulti(Sound sound)
audioBufferPoolChannels[index] = audioBufferPoolCounter; audioBufferPoolChannels[index] = audioBufferPoolCounter;
audioBufferPoolCounter++; audioBufferPoolCounter++;
audioBufferPool[index]->volume = sound.stream.buffer->volume; audioBufferPool[index]->volume = sound.stream.buffer->volume;
audioBufferPool[index]->pitch = sound.stream.buffer->pitch; audioBufferPool[index]->pitch = sound.stream.buffer->pitch;
audioBufferPool[index]->looping = sound.stream.buffer->looping; audioBufferPool[index]->looping = sound.stream.buffer->looping;
@ -1020,12 +1024,12 @@ void StopSoundMulti(void)
int GetSoundsPlaying(void) int GetSoundsPlaying(void)
{ {
int counter = 0; int counter = 0;
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++) for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
{ {
if (IsAudioBufferPlaying(audioBufferPool[i])) counter++; if (IsAudioBufferPlaying(audioBufferPool[i])) counter++;
} }
return counter; return counter;
} }
@ -1208,7 +1212,7 @@ Music LoadMusicStream(const char *fileName)
{ {
drmp3 *ctxMp3 = RL_MALLOC(sizeof(drmp3)); drmp3 *ctxMp3 = RL_MALLOC(sizeof(drmp3));
music.ctxData = ctxMp3; music.ctxData = ctxMp3;
int result = drmp3_init_file(ctxMp3, fileName, NULL); int result = drmp3_init_file(ctxMp3, fileName, NULL);
if (result > 0) if (result > 0)
@ -1239,7 +1243,7 @@ Music LoadMusicStream(const char *fileName)
music.sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); music.sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm);
music.loopCount = 0; // Infinite loop by default music.loopCount = 0; // Infinite loop by default
musicLoaded = true; musicLoaded = true;
music.ctxData = ctxXm; music.ctxData = ctxXm;
} }
} }
@ -1249,7 +1253,7 @@ Music LoadMusicStream(const char *fileName)
{ {
jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t)); jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t));
music.ctxData = ctxMod; music.ctxData = ctxMod;
jar_mod_init(ctxMod); jar_mod_init(ctxMod);
int result = jar_mod_load_file(ctxMod, fileName); int result = jar_mod_load_file(ctxMod, fileName);
@ -1332,7 +1336,7 @@ void PlayMusicStream(Music music)
{ {
// For music streams, we need to make sure we maintain the frame cursor position // For music streams, we need to make sure we maintain the frame cursor position
// This is a hack for this section of code in UpdateMusicStream() // This is a hack for this section of code in UpdateMusicStream()
// NOTE: In case window is minimized, music stream is stopped, just make sure to // NOTE: In case window is minimized, music stream is stopped, just make sure to
// play again on window restore: if (IsMusicPlaying(music)) PlayMusicStream(music); // play again on window restore: if (IsMusicPlaying(music)) PlayMusicStream(music);
ma_uint32 frameCursorPos = audioBuffer->frameCursorPos; ma_uint32 frameCursorPos = audioBuffer->frameCursorPos;
PlayAudioStream(music.stream); // WARNING: This resets the cursor position. PlayAudioStream(music.stream); // WARNING: This resets the cursor position.
@ -1392,7 +1396,7 @@ void UpdateMusicStream(Music music)
void *pcm = RL_CALLOC(subBufferSizeInFrames*music.stream.channels*music.stream.sampleSize/8, 1); void *pcm = RL_CALLOC(subBufferSizeInFrames*music.stream.channels*music.stream.sampleSize/8, 1);
int samplesCount = 0; // Total size of data streamed in L+R samples for xm floats, individual L or R for ogg shorts int samplesCount = 0; // Total size of data streamed in L+R samples for xm floats, individual L or R for ogg shorts
// TODO: Get the sampleLeft using totalFramesProcessed... but first, get total frames processed correctly... // TODO: Get the sampleLeft using totalFramesProcessed... but first, get total frames processed correctly...
//ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels; //ma_uint32 frameSizeInBytes = ma_get_bytes_per_sample(music.stream.buffer->dsp.formatConverterIn.config.formatIn)*music.stream.buffer->dsp.formatConverterIn.config.channels;
int sampleLeft = music.sampleCount - (music.stream.buffer->totalFramesProcessed*music.stream.channels); int sampleLeft = music.sampleCount - (music.stream.buffer->totalFramesProcessed*music.stream.channels);
@ -1446,7 +1450,7 @@ void UpdateMusicStream(Music music)
} }
UpdateAudioStream(music.stream, pcm, samplesCount); UpdateAudioStream(music.stream, pcm, samplesCount);
if ((music.ctxType == MUSIC_MODULE_XM) || (music.ctxType == MUSIC_MODULE_MOD)) if ((music.ctxType == MUSIC_MODULE_XM) || (music.ctxType == MUSIC_MODULE_MOD))
{ {
if (samplesCount > 1) sampleLeft -= samplesCount/2; if (samplesCount > 1) sampleLeft -= samplesCount/2;
@ -1546,11 +1550,11 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
// The size of a streaming buffer must be at least double the size of a period // The size of a streaming buffer must be at least double the size of a period
unsigned int periodSize = device.playback.internalBufferSizeInFrames/device.playback.internalPeriods; unsigned int periodSize = device.playback.internalBufferSizeInFrames/device.playback.internalPeriods;
unsigned int subBufferSize = AUDIO_BUFFER_SIZE; unsigned int subBufferSize = AUDIO_BUFFER_SIZE;
if (subBufferSize < periodSize) subBufferSize = periodSize; if (subBufferSize < periodSize) subBufferSize = periodSize;
stream.buffer = InitAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM); stream.buffer = InitAudioBuffer(formatIn, stream.channels, stream.sampleRate, subBufferSize*2, AUDIO_BUFFER_USAGE_STREAM);
if (stream.buffer != NULL) if (stream.buffer != NULL)
{ {
stream.buffer->looping = true; // Always loop for streaming buffers stream.buffer->looping = true; // Always loop for streaming buffers
@ -1575,7 +1579,7 @@ void CloseAudioStream(AudioStream stream)
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount) void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
{ {
AudioBuffer *audioBuffer = stream.buffer; AudioBuffer *audioBuffer = stream.buffer;
if (audioBuffer != NULL) if (audioBuffer != NULL)
{ {
if (audioBuffer->isSubBufferProcessed[0] || audioBuffer->isSubBufferProcessed[1]) if (audioBuffer->isSubBufferProcessed[0] || audioBuffer->isSubBufferProcessed[1])
@ -1584,7 +1588,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
if (audioBuffer->isSubBufferProcessed[0] && audioBuffer->isSubBufferProcessed[1]) if (audioBuffer->isSubBufferProcessed[0] && audioBuffer->isSubBufferProcessed[1])
{ {
// Both buffers are available for updating. // Both buffers are available for updating.
// Update the first one and make sure the cursor is moved back to the front. // Update the first one and make sure the cursor is moved back to the front.
subBufferToUpdate = 0; subBufferToUpdate = 0;
audioBuffer->frameCursorPos = 0; audioBuffer->frameCursorPos = 0;
@ -1601,7 +1605,7 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
// TODO: Get total frames processed on this buffer... DOES NOT WORK. // TODO: Get total frames processed on this buffer... DOES NOT WORK.
audioBuffer->totalFramesProcessed += subBufferSizeInFrames; audioBuffer->totalFramesProcessed += subBufferSizeInFrames;
// Does this API expect a whole buffer to be updated in one go? // Does this API expect a whole buffer to be updated in one go?
// Assuming so, but if not will need to change this logic. // Assuming so, but if not will need to change this logic.
if (subBufferSizeInFrames >= (ma_uint32)samplesCount/stream.channels) if (subBufferSizeInFrames >= (ma_uint32)samplesCount/stream.channels)
{ {

View File

@ -432,7 +432,7 @@ typedef struct Sound {
typedef struct Music { typedef struct Music {
int ctxType; // Type of music context (audio filetype) int ctxType; // Type of music context (audio filetype)
void *ctxData; // Audio context data, depends on type void *ctxData; // Audio context data, depends on type
unsigned int sampleCount; // Total number of samples unsigned int sampleCount; // Total number of samples
unsigned int loopCount; // Loops count (times music will play), 0 means infinite loop unsigned int loopCount; // Loops count (times music will play), 0 means infinite loop