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 }