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) {