int openal_stream_init(audio_stream *stream, audio_sink *sink) { openal_stream *local = malloc(sizeof(openal_stream)); // Dump old errors int error; while((error = alGetError()) != AL_NO_ERROR); // Pick format local->format = 0; switch(source_get_bytes(stream->src)) { case 1: switch(source_get_channels(stream->src)) { case 1: local->format = AL_FORMAT_MONO8; break; case 2: local->format = AL_FORMAT_STEREO8; break; }; break; case 2: switch(source_get_channels(stream->src)) { case 1: local->format = AL_FORMAT_MONO16; break; case 2: local->format = AL_FORMAT_STEREO16; break; }; break; }; if(!local->format) { PERROR("OpenAL Stream: Could not find suitable audio format!"); goto exit_0; } // Generate a source alGenSources(1, &local->source); if(alGetError() != AL_NO_ERROR) { PERROR("OpenAL Stream: Could not create audio source!"); goto exit_0; } // Generate buffers alGenBuffers(AUDIO_BUFFER_COUNT, local->buffers); if(alGetError() != AL_NO_ERROR) { PERROR("OpenAL Stream: Could not create audio buffers!"); goto exit_1; } // Set callbacks etc. stream_set_userdata(stream, local); stream_set_update_cb(stream, openal_stream_update); stream_set_close_cb(stream, openal_stream_close); stream_set_play_cb(stream, openal_stream_play); stream_set_stop_cb(stream, openal_stream_stop); stream_set_apply_cb(stream, openal_stream_apply); // All done return 0; // Error exits exit_1: alDeleteSources(1, &local->source); exit_0: free(local); return 1; }
int dumb_source_update(audio_source *src, char *buffer, int len) { dumb_source *local = source_get_userdata(src); // Get deltatime and bitrate float delta = 65536.0f / source_get_frequency(src); int bps = source_get_channels(src) * source_get_bytes(src); // If looping is off, and if we have played the whole file, stop here. long pos = duh_sigrenderer_get_position(local->renderer); if(pos < local->vpos && !src->loop) { return 0; } local->vpos = pos; // ... otherwise get more data. int ret = duh_render_int( local->renderer, &local->sig_samples, &local->sig_samples_size, source_get_bytes(src) * 8, // Bits 0, // Unsign 1.0f, // Volume delta, len / bps, // Size buffer ) * bps; return ret; }
void openal_stream_apply(audio_stream *stream) { openal_stream *local = stream_get_userdata(stream); // Handle panning here (only if mono) if(source_get_channels(stream->src) == 1) { float pos[] = {stream->panning, 0.0f, -1.0f}; alSourcefv(local->source, AL_POSITION, pos); } // Volume and pitch alSourcef(local->source, AL_GAIN, stream->volume); alSourcef(local->source, AL_PITCH, stream->pitch); }