static int UpdatePlayer(StreamPlayer *player) { ALint processed, state; /* Get relevant source info */ alGetSourcei(player->source, AL_SOURCE_STATE, &state); alGetSourcei(player->source, AL_BUFFERS_PROCESSED, &processed); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error checking source state\n"); return 0; } /* Unqueue and handle each processed buffer */ while(processed > 0) { ALuint bufid; size_t got; alSourceUnqueueBuffers(player->source, 1, &bufid); processed--; /* Read the next chunk of data, refill the buffer, and queue it * back on the source */ got = readAVAudioData(player->stream, player->data, player->datasize); if(got > 0) { alBufferSamplesSOFT(bufid, player->rate, player->format, BytesToFrames(got, player->channels, player->type), player->channels, player->type, player->data); alSourceQueueBuffers(player->source, 1, &bufid); } if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error buffering data\n"); return 0; } } /* Make sure the source hasn't underrun */ if(state != AL_PLAYING && state != AL_PAUSED) { ALint queued; /* If no buffers are queued, playback is finished */ alGetSourcei(player->source, AL_BUFFERS_QUEUED, &queued); if(queued == 0) return 0; alSourcePlay(player->source); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error restarting playback\n"); return 0; } } return 1; }
/* Prebuffers some audio from the file, and starts playing the source */ static int StartPlayer(StreamPlayer *player) { size_t i, got; /* Rewind the source position and clear the buffer queue */ alSourceRewind(player->source); alSourcei(player->source, AL_BUFFER, 0); /* Fill the buffer queue */ for(i = 0;i < NUM_BUFFERS;i++) { /* Get some data to give it to the buffer */ got = readAVAudioData(player->stream, player->data, player->datasize); if(got == 0) break; alBufferSamplesSOFT(player->buffers[i], player->rate, player->format, BytesToFrames(got, player->channels, player->type), player->channels, player->type, player->data); } if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error buffering for playback\n"); return 0; } /* Now queue and start playback! */ alSourceQueueBuffers(player->source, i, player->buffers); alSourcePlay(player->source); if(alGetError() != AL_NO_ERROR) { fprintf(stderr, "Error starting playback\n"); return 0; } return 1; }
size_t FFmpeg_Decoder::read(char *buffer, size_t bytes) { if(!mStream) fail("No audio stream"); return readAVAudioData(buffer, bytes); }