Browse Source

Corrected audio bugs and improved examples

raysan5 9 years ago
parent
commit
79c8eb543e
3 changed files with 91 additions and 58 deletions
  1. 24 6
      examples/audio_module_playing.c
  2. 26 25
      examples/audio_music_stream.c
  3. 41 27
      src/audio.c

+ 24 - 6
examples/audio_module_playing.c

@@ -62,6 +62,7 @@ int main()
     PlayMusicStream(xm);
 
     float timePlayed = 0.0f;
+    bool pause = false;
 
     SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
     //--------------------------------------------------------------------------------------
@@ -71,7 +72,29 @@ int main()
     {
         // Update
         //----------------------------------------------------------------------------------
-        for (int i = MAX_CIRCLES - 1; i >= 0; i--)
+        UpdateMusicStream(xm);        // Update music buffer with new stream data
+        
+        // Restart music playing (stop and play)
+        if (IsKeyPressed(KEY_SPACE)) 
+        {
+            StopMusicStream(xm);
+            PlayMusicStream(xm);
+        }
+        
+        // Pause/Resume music playing 
+        if (IsKeyPressed(KEY_P))
+        {
+            pause = !pause;
+            
+            if (pause) PauseMusicStream(xm);
+            else ResumeMusicStream(xm);
+        }
+        
+        // Get timePlayed scaled to bar dimensions
+        timePlayed = (GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40))*2;
+        
+        // Color circles animation
+        for (int i = MAX_CIRCLES - 1; (i >= 0) && !pause; i--)
         {
             circles[i].alpha += circles[i].speed;
             circles[i].radius += circles[i].speed*10.0f;
@@ -88,11 +111,6 @@ int main()
                 circles[i].speed = (float)GetRandomValue(1, 100)/20000.0f;
             }
         }
-
-        // Get timePlayed scaled to bar dimensions
-        timePlayed = (GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40))*2;
-        
-        UpdateMusicStream(xm);        // Update music buffer with new stream data
         //----------------------------------------------------------------------------------
 
         // Draw

+ 26 - 25
examples/audio_music_stream.c

@@ -28,9 +28,8 @@ int main()
     
     PlayMusicStream(music);
 
-    int framesCounter = 0;
     float timePlayed = 0.0f;
-    //float volume = 1.0;
+    bool pause = false;
 
     SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
     //--------------------------------------------------------------------------------------
@@ -40,28 +39,26 @@ int main()
     {
         // Update
         //----------------------------------------------------------------------------------
-        framesCounter++;
-
-        // Testing music fading from one file to another
-/*
-        if (framesCounter > 600)    // Wait for 10 seconds (600 frames)
+        UpdateMusicStream(music);        // Update music buffer with new stream data
+        
+        // Restart music playing (stop and play)
+        if (IsKeyPressed(KEY_SPACE)) 
         {
-            volume -= 0.01;         // Decrement music volume level
-
-            // When music volume level equal or lower than 0,
-            // restore volume level and init another music file
-            if (volume <= 0)
-            {
-                volume = 1.0;
-                framesCounter = 0;
-            }
-
-            SetMusicVolume(volume);
+            StopMusicStream(music);
+            PlayMusicStream(music);
         }
-*/
-        timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4; // We scale by 4 to fit 400 pixels
-
-        UpdateMusicStream(music);        // Update music buffer with new stream data
+        
+        // Pause/Resume music playing 
+        if (IsKeyPressed(KEY_P))
+        {
+            pause = !pause;
+            
+            if (pause) PauseMusicStream(music);
+            else ResumeMusicStream(music);
+        }
+        
+        // Get timePlayed scaled to bar dimensions (400 pixels)
+        timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4;
         //----------------------------------------------------------------------------------
 
         // Draw
@@ -70,10 +67,14 @@ int main()
 
             ClearBackground(RAYWHITE);
 
-            DrawText("MUSIC SHOULD BE PLAYING!", 255, 200, 20, LIGHTGRAY);
+            DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
 
-            DrawRectangle(200, 250, 400, 12, LIGHTGRAY);
-            DrawRectangle(200, 250, (int)timePlayed, 12, MAROON);
+            DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
+            DrawRectangle(200, 200, (int)timePlayed, 12, MAROON);
+            DrawRectangleLines(200, 200, 400, 12, GRAY);
+            
+            DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
+            DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
 
         EndDrawing();
         //----------------------------------------------------------------------------------

+ 41 - 27
src/audio.c

@@ -225,12 +225,16 @@ Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, in
     wave.data = data;
     wave.sampleCount = sampleCount;
     wave.sampleRate = sampleRate;
-    wave.sampleSize = sampleSize;
+    wave.sampleSize = 32;
     wave.channels = channels;
     
-    WaveFormat(&wave, sampleRate, sampleSize, channels);
+    // NOTE: Copy wave data to work with, 
+    // user is responsible of input data to free
+    Wave cwave = WaveCopy(wave);
     
-    return wave;
+    WaveFormat(&cwave, sampleRate, sampleSize, channels);
+    
+    return cwave;
 }
 
 // Load sound to memory
@@ -578,6 +582,8 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
             }
         }
         else TraceLog(WARNING, "Wave formatting: Sample size not supported");
+        
+        free(samples);
     }
     
     // NOTE: Only supported 1 or 2 channels (mono or stereo)
@@ -615,7 +621,8 @@ Wave WaveCopy(Wave wave)
 // NOTE: Security check in case of out-of-range
 void WaveCrop(Wave *wave, int initSample, int finalSample)
 {
-    if ((initSample >= 0) && (finalSample > 0) && (finalSample < wave->sampleCount))
+    if ((initSample >= 0) && (initSample < finalSample) && 
+        (finalSample > 0) && (finalSample < wave->sampleCount))
     {
         // TODO: Review cropping (it could be simplified...)
         
@@ -636,6 +643,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample)
 
 // Get samples data from wave as a floats array
 // NOTE: Returned sample values are normalized to range [-1..1]
+// TODO: Consider multiple channels (mono - stereo)
 float *GetWaveData(Wave wave)
 {
     float *samples = (float *)malloc(wave.sampleCount*sizeof(float));
@@ -759,26 +767,37 @@ void ResumeMusicStream(Music music)
 }
 
 // Stop music playing (close stream)
+// TODO: Restart XM context
 void StopMusicStream(Music music)
 {
     alSourceStop(music->stream.source);
+    
+    switch (music->ctxType)
+    {
+        case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break;
+        case MUSIC_MODULE_XM: break;
+        case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break;
+        default: break;
+    }
+    
+    music->samplesLeft = music->totalSamples;
 }
 
 // Update (re-fill) music buffers if data already processed
 void UpdateMusicStream(Music music)
 {
+    ALenum state;
     ALint processed = 0;
-
-    // Determine if music stream is ready to be written
-    alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed);
-
-    int numBuffersToProcess = processed;
+    
+    alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state);          // Get music stream state
+    alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); // Get processed buffers
 
     if (processed > 0)
     {
         bool active = true;
         short pcm[AUDIO_BUFFER_SIZE];
         float pcmf[AUDIO_BUFFER_SIZE];
+        int numBuffersToProcess = processed;
 
         int numSamples = 0;     // Total size of data steamed in L+R samples for xm floats,
                                 // individual L or R for ogg shorts
@@ -833,28 +852,23 @@ void UpdateMusicStream(Music music)
                 break;
             }
         }
+        
+        // This error is registered when UpdateAudioStream() fails
+        if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data...");
 
         // Reset audio stream for looping
-        if (!active && music->loop)
+        if (!active) 
         {
-            // Restart music context (if required)
-            //if (music->ctxType == MUSIC_MODULE_XM)
-            if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_seek_start(&music->ctxMod);
-            else if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_seek_start(music->ctxOgg);
-
-            // Reset samples left to total samples
-            music->samplesLeft = music->totalSamples;
+            StopMusicStream(music);        // Stop music (and reset)
+            
+            if (music->loop) PlayMusicStream(music);    // Play again
+        }
+        else
+        {
+            // NOTE: In case window is minimized, music stream is stopped,
+            // just make sure to play again on window restore
+            if (state != AL_PLAYING) PlayMusicStream(music);
         }
-
-        // This error is registered when UpdateAudioStream() fails
-        if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data...");
-
-        ALenum state;
-        alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state);
-
-        if (state != AL_PLAYING && active) alSourcePlay(music->stream.source);
-
-        if (!active) StopMusicStream(music);
     }
 }