diff --git a/src/Reveal.hpp b/src/Reveal.hpp index a9d3561893d88b5163ae56f5133c8aaa9cf939a2..b89a56362627bc0eed68385e5c2609e6f0cc3f6f 100644 --- a/src/Reveal.hpp +++ b/src/Reveal.hpp @@ -79,7 +79,7 @@ class Reveal : public GroupModule { POSTFILTER, RENDERTEX, AUDIOTEX, AUDIORATE, MAXAUDIOVALUE, AUDIOBUFSIZE, AUDIOMIXSIZE, - PROCESSAUDIO + PROCESSAUDIO, AUDIONEXTBUF }; enum GEOM_ID { diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp index a3a139d8a34b26e09fbc87f989bdd0b0a0bd4151..fdc4f2e54742a328cc83ab80bf28dde28eff7642 100644 --- a/src/audio/AudioManager.cpp +++ b/src/audio/AudioManager.cpp @@ -65,8 +65,6 @@ int AudioManager::rtaudio_callback(void *outbuf, void *inbuf, unsigned int nFram float cnt = 0.0; for(int i=0; i < nFrames; ++i) { buf[i*2] = data->buffer[i]*cnt + data->mixBuffer[i]*(1.0-cnt); - //buf[i*2] = data->mixBuffer[i]*(1.0-cnt); - //buf[i*2] = data->buffer[i]*cnt; buf[i*2+1] = buf[i*2]; cnt+=step; } @@ -83,7 +81,7 @@ int AudioManager::rtaudio_callback(void *outbuf, void *inbuf, unsigned int nFram } else { //read the next buffer - for(int i=0; i < nFrames; ++i) { + for(int i=0; i<nFrames; ++i) { buf[i*2] = data->buffer[data->bufCounter*nFrames+i]; buf[i*2+1] = buf[i*2]; } @@ -100,7 +98,7 @@ AudioManager::AudioManager() { } void AudioManager::init() { - //audio = new RtAudio(RtAudio::LINUX_PULSE); + //m_rtAudio = new RtAudio(RtAudio::LINUX_PULSE); m_rtAudio = new RtAudio(RtAudio::UNIX_JACK); param = new RtAudio::StreamParameters(); param->deviceId = m_rtAudio->getDefaultOutputDevice(); @@ -136,44 +134,18 @@ void AudioManager::init() { } -void AudioManager::changeBuf(float* outputBuf, float maxSinValue) { +bool AudioManager::changeBuf(float* outputBuf, float maxSinValue) { if(m_init) { - //check if there is space to write the new values size_t write_space = ringbuffer_write_space(data.ringBuffer); if(write_space >= m_bufSize) { - - //write all data to the ringbuffer ringbuffer_write(data.ringBuffer, outputBuf, data.bufSize); - - /* - float phase = 0; - float pas = 1.0/float(data.mixSize); - - //fill the audioValue array with the audio value - for(int i=0; i < int(data.nFrames); i++) { - if(i < data.mixSize) { - audioValue[i] = outputBuf[i]*phase; - phase += pas; - } - else { - audioValue[i] = outputBuf[i]; - } - } - - //fill the audioValue array with the values for the next crossfading - for(int i=0; i<data.mixSize; i++) { - audioValue[data.nFrames+i] = outputBuf[data.nFrames+i]*phase; - phase-=pas; - } - constAudioValue = const_cast<const float *>(audioValue); - - ringbuffer_write(data.audioBuf, constAudioValue, data.nFrames + data.mixSize); - */ + return true; } else { //cout<<"AudioManager : Could not write buffer"<<endl; + return false; } } } diff --git a/src/audio/AudioManager.hpp b/src/audio/AudioManager.hpp index 600c86d27bb18201606c7c26da3608e7a735a9b4..3e0107214607c2704087fba1fd2c66d9f0e0c819 100644 --- a/src/audio/AudioManager.hpp +++ b/src/audio/AudioManager.hpp @@ -67,7 +67,7 @@ class AudioManager { static AudioManager* getInstance(); ~AudioManager(); void init(); - void changeBuf(float* outputBuf, float maxSinValue); + bool changeBuf(float* outputBuf, float maxSinValue); int getRate(); int getBufferSize(); int getMixSize(); diff --git a/src/modules/ProjectorModule.cpp b/src/modules/ProjectorModule.cpp index 0d920423d013f23b83d4b7cd44d5e22808324b99..f3133f60eb479574d4e7575fc66eec72c713e1b5 100644 --- a/src/modules/ProjectorModule.cpp +++ b/src/modules/ProjectorModule.cpp @@ -192,13 +192,14 @@ ProjectorModule::ProjectorModule(): Module() { //audio m_nbTracks=50; - m_maxAudioValue = (std::numeric_limits<int>::max())/(m_width * m_height); + //m_maxAudioValue = (std::numeric_limits<int>::max())/(m_width * m_height); + m_maxAudioValue = (std::numeric_limits<int>::max())/(m_width); m_audioMixSize = AudioManager::getInstance()->getMixSize(); m_audioBufSize = AudioManager::getInstance()->getBufferSize(); - // + m_audioMixSize; m_imgBufSize = m_audioBufSize+3; m_audioBuffer = new float[m_audioBufSize]; memset(&m_audioBuffer[0], 0, m_audioBufSize*sizeof(float)); + m_audioNextBuf=1; Reveal::getInstance()->addContextHandler(this); @@ -356,6 +357,8 @@ void ProjectorModule::draw() { m_audioBufSize); glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::AUDIOMIXSIZE], m_audioMixSize); + glUniform1i(m_uniforms[Reveal::RENDERPROG][Reveal::AUDIONEXTBUF], + m_audioNextBuf); #endif //Draw everything @@ -566,8 +569,8 @@ void ProjectorModule::initGL() { //Audio texture m_audioImg = new int[m_imgBufSize*m_nbTracks]; memset(&m_audioImg[0], 0, m_imgBufSize*m_nbTracks*sizeof(int)); - m_audioImgInit = new int[2*m_nbTracks]; - memset(&m_audioImgInit[0], 0, 2*m_nbTracks*sizeof(int)); + m_audioImgInit = new int[3*m_nbTracks]; + memset(&m_audioImgInit[0], 0, 3*m_nbTracks*sizeof(int)); glGenTextures(1, &m_audioTex); glBindTexture(GL_TEXTURE_2D, m_audioTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -588,6 +591,8 @@ void ProjectorModule::initGL() { = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "maxAudioValue"); m_uniforms[Reveal::RENDERPROG][Reveal::AUDIORATE] = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "audioRate"); + m_uniforms[Reveal::RENDERPROG][Reveal::AUDIONEXTBUF] + = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "audioNextBuf"); m_uniforms[Reveal::RENDERPROG][Reveal::OUTPUTTEX] = glGetUniformLocation(m_programs[Reveal::RENDERPROG], "outputTex"); @@ -1021,18 +1026,16 @@ void ProjectorModule::processAudio() { float trackGain = m_audioImg[m_imgBufSize * i]; if(trackGain>0) { totalGains += trackGain; - //compute the new phase for the note i - //m_phase[i] = (m_phase[i] + bufSize - 2 - mixSize) % m_outputAudio[ (bufSize*i) + 1]; - //convert the audio value from int to float and save it in outputAudio + //Mix all tracks with gain from number of voxels for(int j=0; j<m_audioBufSize; j++) { m_audioBuffer[j] += trackGain * (float(m_audioImg[(m_imgBufSize*i)+3+j]) / m_maxAudioValue); } - // cout<<"read phase "<<i<<" " - // <<float(m_audioImg[m_imgBufSize*i+1])/m_maxAudioValue<<endl; - // cout<<"nb frags = "<<m_audioImg[m_imgBufSize*i]<<endl; - m_audioImgInit[2*i+1] = m_audioImg[m_imgBufSize*i+2]; + + //copy the old and new phases + m_audioImgInit[3*i+1] = m_audioImg[m_imgBufSize*i+1]; + m_audioImgInit[3*i+2] = m_audioImg[m_imgBufSize*i+2]; } } @@ -1042,19 +1045,21 @@ void ProjectorModule::processAudio() { for(int i=0; i<m_audioBufSize; i++) { m_audioBuffer[i] = gain*m_audioBuffer[i]/totalGains; } - AudioManager::getInstance()->changeBuf(m_audioBuffer, m_maxAudioValue); + m_audioNextBuf = AudioManager::getInstance()->changeBuf(m_audioBuffer, + m_maxAudioValue); memset(&m_audioBuffer[0], 0, (m_audioBufSize)*sizeof(float)); } else{ memset(&m_audioBuffer[0], 0, (m_audioBufSize)*sizeof(float)); - AudioManager::getInstance()->changeBuf(m_audioBuffer, m_maxAudioValue); + m_audioNextBuf = AudioManager::getInstance()->changeBuf(m_audioBuffer, + m_maxAudioValue); } - //reset the first column of audio values + //reset the gain and transfer the old and new phases glBindTexture(GL_TEXTURE_2D, m_audioTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, m_nbTracks, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 3, m_nbTracks, GL_RED_INTEGER, GL_INT, &m_audioImgInit[0]); } diff --git a/src/modules/ProjectorModule.hpp b/src/modules/ProjectorModule.hpp index 3c3e2a26ad4b9b30d9d8fabe4d32e8793d3eab53..4370ae1cc50a8fdf4e3082cba091626e2cd9430c 100644 --- a/src/modules/ProjectorModule.hpp +++ b/src/modules/ProjectorModule.hpp @@ -239,6 +239,7 @@ class ProjectorModule : public Module, public ContextHandler { int m_imgBufSize; float* m_audioBuffer; float m_maxAudioValue; + int m_audioNextBuf; }; diff --git a/src/shaders/render43.fs b/src/shaders/render43.fs index 80a280135135c0f9629cb2c45bff10d81ec0b498..aea1ba491225ce26a5f2d969416e6c705571d494 100644 --- a/src/shaders/render43.fs +++ b/src/shaders/render43.fs @@ -28,6 +28,7 @@ uniform int audioBufSize; uniform float maxAudioValue; uniform int audioRate; uniform int processAudio; +uniform int audioNextBuf; uniform float viewportWidth; uniform float viewportHeight; @@ -135,42 +136,36 @@ void additiveSynth(vec4 color) { } //count this fragment - imageAtomicAdd(audioTex, ivec2(0, ind), 1); - - //if the audio has not been generated by another fragment - if(imageLoad(audioTex, ivec2(0, ind)).x<=1) { + if(imageAtomicAdd(audioTex, ivec2(0, ind), 1)<1) { + //if the audio has not been generated by another fragment //compute frequency freq = float(440.0 * pow(2.0, (note-69.0)/12.0)); - //retrieve phase stored from previous frame - float phase = float(imageLoad(audioTex, ivec2(1, ind)).x) - / maxAudioValue; + //retrieve either new or old phase, depending on if audio was processed + float phase = float(imageLoad(audioTex, ivec2(1, ind)).x); + if(audioNextBuf>0) {//if new phase + //retrieve it + phase = float(imageLoad(audioTex, ivec2(2, ind)).x); + //store it as previous phase + imageStore(audioTex, ivec2(1, ind), ivec4(int(phase))); + } + float outputPhase = phase; - float samplesPerPeriod = audioRate/freq; - float phaseStep = 1.0/samplesPerPeriod; + float samplesPerPeriod = (audioRate/freq); + float phaseStep = 1.0; for(int i=0; i<audioBufSize; i++) { - //compute value - float s = sin(phase * 2.0 * M_PI); - - //write starting from 3rd column + //compute and store value starting from 3rd column + float s = sin((phase/samplesPerPeriod) * 2.0 * M_PI); imageStore(audioTex, ivec2(i+3, ind), ivec4(int(s*maxAudioValue))); - phase=mod(phase + phaseStep, 1.0); - } - /* - float a = 2.0*sin(freq/float(audioRate)); - float s[2]; - s[0] = 1.0f; - s[1] = 0.0f; - for(int i=0; i<audioBufSize; i++) { - imageStore(audioTex, ivec2(i+3, ind), ivec4(int(s[1]*maxAudioValue))); - s[0] = s[0] - a*s[1]; - s[1] = s[1] + a*s[0]; - }*/ + //increase phase + phase=mod(phase + phaseStep, samplesPerPeriod); + } //remove audioMixSize steps and write phase to output - outputPhase = mod(outputPhase+phaseStep*(audioBufSize-audioMixSize), 1.0); - imageStore(audioTex, ivec2(2, ind), - ivec4(int(outputPhase*maxAudioValue))); + outputPhase=mod(outputPhase+phaseStep*(audioBufSize-audioMixSize), + samplesPerPeriod); + //outputPhase=mod(outputPhase+phaseStep*(audioBufSize), 1.0); + imageStore(audioTex, ivec2(2, ind), ivec4(int(outputPhase))); } }