示例#1
0
文件: audio.c 项目: MarcMDE/raylib
// Start music playing (open stream)
void PlayMusicStream(char *fileName)
{
    if (strcmp(GetExtension(fileName),"ogg") == 0)
    {
        // Stop current music, clean buffers, unload current stream
        StopMusicStream();

        // Open audio stream
        currentMusic.stream = stb_vorbis_open_filename(fileName, NULL, NULL);

        if (currentMusic.stream == NULL)
        {
            TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
        }
        else
        {
            // Get file info
            stb_vorbis_info info = stb_vorbis_get_info(currentMusic.stream);

            currentMusic.channels = info.channels;
            currentMusic.sampleRate = info.sample_rate;

            TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
            TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
            TraceLog(INFO, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);

            if (info.channels == 2) currentMusic.format = AL_FORMAT_STEREO16;
            else currentMusic.format = AL_FORMAT_MONO16;

            currentMusic.loop = true;                  // We loop by default
            musicEnabled = true;

            // Create an audio source
            alGenSources(1, &currentMusic.source);     // Generate pointer to audio source

            alSourcef(currentMusic.source, AL_PITCH, 1);
            alSourcef(currentMusic.source, AL_GAIN, 1);
            alSource3f(currentMusic.source, AL_POSITION, 0, 0, 0);
            alSource3f(currentMusic.source, AL_VELOCITY, 0, 0, 0);
            //alSourcei(currentMusic.source, AL_LOOPING, AL_TRUE);     // ERROR: Buffers do not queue!

            // Generate two OpenAL buffers
            alGenBuffers(2, currentMusic.buffers);

            // Fill buffers with music...
            BufferMusicStream(currentMusic.buffers[0]);
            BufferMusicStream(currentMusic.buffers[1]);

            // Queue buffers and start playing
            alSourceQueueBuffers(currentMusic.source, 2, currentMusic.buffers);
            alSourcePlay(currentMusic.source);

            // NOTE: Regularly, we must check if a buffer has been processed and refill it: MusicStreamUpdate()

            currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
        }
    }
    else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
}
示例#2
0
文件: audio.c 项目: Danlestal/raylib
// Update (re-fill) music buffers if data already processed
extern void UpdateMusicStream()
{
    ALuint buffer = 0;
    ALint processed = 0;
    bool active = true;
    
    if (musicEnabled)
    {
        // Get the number of already processed buffers (if any)
        alGetSourcei(currentMusic.source, AL_BUFFERS_PROCESSED, &processed);
        
        while (processed > 0)
        {
            // Recover processed buffer for refill
            alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);

            // Refill buffer
            active = BufferMusicStream(buffer);
            
            // If no more data to stream, restart music (if loop)
            if ((!active) && (currentMusic.loop))   
            {
                if (currentMusic.loop)
                {
                    stb_vorbis_seek_start(currentMusic.stream);
                    currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
                    
                    active = BufferMusicStream(buffer);
                }
            }
            
            // Add refilled buffer to queue again... don't let the music stop!
            alSourceQueueBuffers(currentMusic.source, 1, &buffer);
            
            if(alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Ogg playing, error buffering data...");
            
            processed--;
        }
        
        ALenum state;
        alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
        
        if ((state != AL_PLAYING) && active) alSourcePlay(currentMusic.source);
        
        if (!active) StopMusicStream();
    }
}