Skip to content
Snippets Groups Projects
Commit 0667b830 authored by Florent Berthaut's avatar Florent Berthaut
Browse files

Fixed additive synthesis

parent 20299383
No related branches found
No related tags found
No related merge requests found
......@@ -79,7 +79,7 @@ class Reveal : public GroupModule {
POSTFILTER, RENDERTEX,
AUDIOTEX, AUDIORATE, MAXAUDIOVALUE, AUDIOBUFSIZE, AUDIOMIXSIZE,
PROCESSAUDIO
PROCESSAUDIO, AUDIONEXTBUF
};
enum GEOM_ID {
......
......@@ -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;
}
......@@ -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;
}
}
}
......
......@@ -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();
......
......@@ -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]);
}
......
......@@ -239,6 +239,7 @@ class ProjectorModule : public Module, public ContextHandler {
int m_imgBufSize;
float* m_audioBuffer;
float m_maxAudioValue;
int m_audioNextBuf;
};
......
......@@ -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(imageAtomicAdd(audioTex, ivec2(0, ind), 1)<1) {
//if the audio has not been generated by another fragment
if(imageLoad(audioTex, ivec2(0, ind)).x<=1) {
//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)));
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment