dungeon_crawler

diff prototype/src/audio/stream.cc @ 56:f9b8bbebc9b3

fixed the music playback
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 20 Sep 2012 10:04:25 +0300
parents 4c427e28ca00
children 45172d087ebe
line diff
     1.1 --- a/prototype/src/audio/stream.cc	Wed Sep 19 08:19:10 2012 +0300
     1.2 +++ b/prototype/src/audio/stream.cc	Thu Sep 20 10:04:25 2012 +0300
     1.3 @@ -1,4 +1,5 @@
     1.4  #include <stdio.h>
     1.5 +#include <assert.h>
     1.6  #include "stream.h"
     1.7  #include "openal.h"
     1.8  
     1.9 @@ -8,6 +9,7 @@
    1.10  	poll_interval = 250;
    1.11  	done = true;
    1.12  	loop = false;
    1.13 +	volume = 1.0;
    1.14  }
    1.15  
    1.16  AudioStream::~AudioStream()
    1.17 @@ -15,6 +17,21 @@
    1.18  	stop();
    1.19  }
    1.20  
    1.21 +void AudioStream::set_volume(float vol)
    1.22 +{
    1.23 +	volume = vol;
    1.24 +
    1.25 +	std::lock_guard<std::mutex> lock(mutex);
    1.26 +	if(alsrc) {
    1.27 +		alSourcef(alsrc, AL_GAIN, vol);
    1.28 +	}
    1.29 +}
    1.30 +
    1.31 +float AudioStream::get_volume() const
    1.32 +{
    1.33 +	return volume;
    1.34 +}
    1.35 +
    1.36  void AudioStream::play(enum PlayMode mode)
    1.37  {
    1.38  	loop = (mode == PlayMode::loop);
    1.39 @@ -24,12 +41,15 @@
    1.40  
    1.41  void AudioStream::stop()
    1.42  {
    1.43 -	std::lock_guard<std::mutex> lock(mutex);
    1.44 -
    1.45 +	mutex.lock();
    1.46  	if(alsrc) {
    1.47  		done = true;
    1.48  		alSourceStop(alsrc);
    1.49 +		printf("waiting for the music thread to stop\n");
    1.50 +		mutex.unlock();
    1.51  		play_thread.join();
    1.52 +	} else {
    1.53 +		mutex.unlock();
    1.54  	}
    1.55  }
    1.56  
    1.57 @@ -47,6 +67,9 @@
    1.58  	mutex.lock();
    1.59  
    1.60  	alGenSources(1, &alsrc);
    1.61 +	alSourcei(alsrc, AL_LOOPING, AL_FALSE);
    1.62 +	alSourcef(alsrc, AL_GAIN, volume);
    1.63 +
    1.64  	alGenBuffers(num_buffers, albuf);
    1.65  
    1.66  	AudioStreamBuffer *buf = new AudioStreamBuffer;
    1.67 @@ -54,7 +77,6 @@
    1.68  	for(int i=0; i<num_buffers; i++) {
    1.69  		if(more_samples(buf)) {
    1.70  			int bufsz = buf->num_samples * buf->channels * 2;	// 2 is for 16bit samples
    1.71 -			printf("buffer data: %d samples, %d rate, %d channels\n", buf->num_samples, buf->sample_rate, buf->channels);
    1.72  			alBufferData(albuf[i], alformat(buf), buf->samples, bufsz, buf->sample_rate);
    1.73  			if(alGetError()) {
    1.74  				fprintf(stderr, "failed to load sample data into OpenAL buffer\n");
    1.75 @@ -70,30 +92,43 @@
    1.76  	}
    1.77  	// start playback
    1.78  	alSourcePlay(alsrc);
    1.79 -	mutex.unlock();
    1.80  
    1.81  	while(!done) {
    1.82 -		mutex.lock();
    1.83  		/* find out how many (if any) of the queued buffers are
    1.84  		 * done, and free to be reused.
    1.85  		 */
    1.86  		int num_buf_done;
    1.87  		alGetSourcei(alsrc, AL_BUFFERS_PROCESSED, &num_buf_done);
    1.88  		for(int i=0; i<num_buf_done; i++) {
    1.89 +			int err;
    1.90  			// unqueue a buffer...
    1.91  			unsigned int buf_id;
    1.92  			alSourceUnqueueBuffers(alsrc, 1, &buf_id);
    1.93 +			if((err = alGetError())) {
    1.94 +				fprintf(stderr, "failed to unqueue used buffer (error: %x)\n", err);
    1.95 +				num_buf_done = i;
    1.96 +				break;
    1.97 +			}
    1.98 +
    1.99 +			int looping;
   1.100 +			alGetSourcei(alsrc, AL_LOOPING, &looping);
   1.101 +			assert(looping == AL_FALSE);
   1.102 +
   1.103 +			int cur_buf;
   1.104 +			alGetSourcei(alsrc, AL_BUFFER, &cur_buf);
   1.105 +			if((unsigned int)cur_buf == buf_id) {
   1.106 +				continue;
   1.107 +			}
   1.108  
   1.109  			// if there are more data, fill it up and requeue it
   1.110  			if(more_samples(buf)) {
   1.111  				int bufsz = buf->num_samples * buf->channels * 2;	// 2 is for 16bit samples
   1.112 -				printf("buffer data: %d samples, %d rate, %d channels\n", buf->num_samples, buf->sample_rate, buf->channels);
   1.113  				alBufferData(buf_id, alformat(buf), buf->samples, bufsz, buf->sample_rate);
   1.114 -				if(alGetError()) {
   1.115 -					fprintf(stderr, "failed to load sample data into OpenAL buffer\n");
   1.116 +				if((err = alGetError())) {
   1.117 +					fprintf(stderr, "failed to load sample data into OpenAL buffer (error: %x)\n", err);
   1.118  				}
   1.119  
   1.120 -				alSourceQueueBuffers(alsrc, 1, albuf + i);
   1.121 +				alSourceQueueBuffers(alsrc, 1, &buf_id);
   1.122  				if(alGetError()) {
   1.123  					fprintf(stderr, "failed to start streaming audio buffers\n");
   1.124  				}
   1.125 @@ -120,10 +155,10 @@
   1.126  
   1.127  		std::chrono::milliseconds dur{poll_interval};
   1.128  		std::this_thread::sleep_for(dur);
   1.129 +
   1.130 +		mutex.lock();
   1.131  	}
   1.132  
   1.133 -	mutex.lock();
   1.134 -
   1.135  	// done with the data, wait for the source to stop playing before cleanup
   1.136  	int state;
   1.137  	while(alGetSourcei(alsrc, AL_SOURCE_STATE, &state), state == AL_PLAYING) {