dungeon_crawler

diff prototype/src/audio/stream.cc @ 55:4c427e28ca00

music playback bugfixing
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 19 Sep 2012 08:19:10 +0300
parents 995191474cc0
children f9b8bbebc9b3
line diff
     1.1 --- a/prototype/src/audio/stream.cc	Wed Sep 19 05:22:43 2012 +0300
     1.2 +++ b/prototype/src/audio/stream.cc	Wed Sep 19 08:19:10 2012 +0300
     1.3 @@ -15,15 +15,17 @@
     1.4  	stop();
     1.5  }
     1.6  
     1.7 -void AudioStream::play(bool loop)
     1.8 +void AudioStream::play(enum PlayMode mode)
     1.9  {
    1.10 -	this->loop = loop;
    1.11 +	loop = (mode == PlayMode::loop);
    1.12  	done = false;
    1.13  	play_thread = std::thread(&AudioStream::poll_loop, this);
    1.14  }
    1.15  
    1.16  void AudioStream::stop()
    1.17  {
    1.18 +	std::lock_guard<std::mutex> lock(mutex);
    1.19 +
    1.20  	if(alsrc) {
    1.21  		done = true;
    1.22  		alSourceStop(alsrc);
    1.23 @@ -40,21 +42,38 @@
    1.24  void AudioStream::poll_loop()
    1.25  {
    1.26  	static const int num_buffers = 3;
    1.27 -	AudioStreamBuffer buf;
    1.28  	unsigned int albuf[num_buffers];
    1.29  
    1.30 +	mutex.lock();
    1.31 +
    1.32  	alGenSources(1, &alsrc);
    1.33  	alGenBuffers(num_buffers, albuf);
    1.34  
    1.35 +	AudioStreamBuffer *buf = new AudioStreamBuffer;
    1.36 +
    1.37  	for(int i=0; i<num_buffers; i++) {
    1.38 -		if(more_samples(&buf)) {
    1.39 +		if(more_samples(buf)) {
    1.40 +			int bufsz = buf->num_samples * buf->channels * 2;	// 2 is for 16bit samples
    1.41 +			printf("buffer data: %d samples, %d rate, %d channels\n", buf->num_samples, buf->sample_rate, buf->channels);
    1.42 +			alBufferData(albuf[i], alformat(buf), buf->samples, bufsz, buf->sample_rate);
    1.43 +			if(alGetError()) {
    1.44 +				fprintf(stderr, "failed to load sample data into OpenAL buffer\n");
    1.45 +			}
    1.46 +
    1.47  			alSourceQueueBuffers(alsrc, 1, albuf + i);
    1.48 +			if(alGetError()) {
    1.49 +				fprintf(stderr, "failed to start streaming audio buffers\n");
    1.50 +			}
    1.51  		} else {
    1.52  			break;
    1.53  		}
    1.54  	}
    1.55 +	// start playback
    1.56 +	alSourcePlay(alsrc);
    1.57 +	mutex.unlock();
    1.58  
    1.59  	while(!done) {
    1.60 +		mutex.lock();
    1.61  		/* find out how many (if any) of the queued buffers are
    1.62  		 * done, and free to be reused.
    1.63  		 */
    1.64 @@ -66,12 +85,18 @@
    1.65  			alSourceUnqueueBuffers(alsrc, 1, &buf_id);
    1.66  
    1.67  			// if there are more data, fill it up and requeue it
    1.68 -			if(more_samples(&buf)) {
    1.69 -				int bufsz = buf.num_samples * buf.channels * 2;	// 2 is for 16bit samples
    1.70 -				alBufferData(buf_id, alformat(&buf), buf.samples, bufsz, buf.sample_rate);
    1.71 +			if(more_samples(buf)) {
    1.72 +				int bufsz = buf->num_samples * buf->channels * 2;	// 2 is for 16bit samples
    1.73 +				printf("buffer data: %d samples, %d rate, %d channels\n", buf->num_samples, buf->sample_rate, buf->channels);
    1.74 +				alBufferData(buf_id, alformat(buf), buf->samples, bufsz, buf->sample_rate);
    1.75  				if(alGetError()) {
    1.76  					fprintf(stderr, "failed to load sample data into OpenAL buffer\n");
    1.77  				}
    1.78 +
    1.79 +				alSourceQueueBuffers(alsrc, 1, albuf + i);
    1.80 +				if(alGetError()) {
    1.81 +					fprintf(stderr, "failed to start streaming audio buffers\n");
    1.82 +				}
    1.83  			} else {
    1.84  				// no more data...
    1.85  				if(loop) {
    1.86 @@ -91,10 +116,14 @@
    1.87  			}
    1.88  		}
    1.89  
    1.90 +		mutex.unlock();
    1.91 +
    1.92  		std::chrono::milliseconds dur{poll_interval};
    1.93  		std::this_thread::sleep_for(dur);
    1.94  	}
    1.95  
    1.96 +	mutex.lock();
    1.97 +
    1.98  	// done with the data, wait for the source to stop playing before cleanup
    1.99  	int state;
   1.100  	while(alGetSourcei(alsrc, AL_SOURCE_STATE, &state), state == AL_PLAYING) {
   1.101 @@ -104,4 +133,6 @@
   1.102  	alDeleteBuffers(num_buffers, albuf);
   1.103  	alDeleteSources(1, &alsrc);
   1.104  	alsrc = 0;
   1.105 +
   1.106 +	mutex.unlock();
   1.107  }