I’m trying to get input from two audio sources and then output them with amplification.
@burton just helped me to get multiple audio inputs working. The two audioInputs use this method to set up their input:
AudioClient class (ofxCustomSetup.h)
bool setup(int ind, size_t bufferSize, std::size_t sr, std::string deviceName)
{
m_deviceIndex = ind;
m_soundL.assign(bufferSize, 0.0f);
m_soundR.assign(bufferSize, 0.0f);
ofLogNotice("desiring device named") << deviceName;
auto devices = m_soundStream.getDeviceList(ofSoundDevice::Api::MS_DS); //no asio option for these webcams
for (int i = 0; i < devices.size(); ++i) {
std::cout << "device " << i << ": " << devices[i].name << endl;
if (devices[i].name == deviceName) {
std::cout << "setting audio device " << i << ": " << devices[i].name << endl;
m_soundSettings.setInDevice(devices[i]);
m_soundSettings.setInListener(this);
m_soundSettings.numInputChannels = 2;
m_soundSettings.sampleRate = sr;
m_soundSettings.numBuffers = 2;
m_soundSettings.bufferSize = bufferSize;
m_soundStream.setup(m_soundSettings);
return true;
}
}
return false;
}
};
ofxCustomSetup.cpp
void ofxCustomSetup::audioInSetup(std::string deviceName)
{
int ind = m_inIndex;
std::shared_ptr<AudioClient> a = std::make_shared<AudioClient>();
m_audioClients.push_back(a);
m_audioInsRMS.push_back(0.0f);
bool set = m_audioClients[ind]->setup(ind, 256, 32000, deviceName); //the camera microphones have a sample rate of 32000
if (set)
{
m_inIndex++;
}
}
The audioIn override uses this method (from examples/ audioInputExample) which saves the input buffer to two arrays:
float getRMS(ofSoundBuffer& buffer)
{
for (size_t i = 0; i < buffer.getNumFrames(); i++) {
m_soundL[i] = buffer[i * 2] * 0.5; //this is what was in the original oF example code, implying that every other sample is from a different channel...?
m_soundR[i] = buffer[i * 2 + 1] * 0.5;
//m_soundL[i] = buffer.getSample(i, 0); //tried changing the code to this but it didn't change the result
//m_soundR[i] = buffer.getSample(i, 1);
//...code for getting RMS of the amplitude
}
}
In ofApp, I make a single audioOut override with a third soundstream:
void ofApp::audioOutSetup()
{
int bufferSize = 256;
ofSoundStreamSettings settings;
auto devices = m_outStream.getDeviceList(ofSoundDevice::Api::MS_DS); //result is same with ASIO
int outDevInd = 0;
for (int i = 0; i < devices.size(); ++i)
{
if (devices[i].name == m_speakersName)
{
outDevInd = i;
std::cout << "setting audio out device " << i << ": " << devices[i].name << endl;
break;
}
}
ofSoundDevice& outDevice = devices[outDevInd];
settings.setOutDevice(outDevice);
settings.setOutListener(this);
settings.numBuffers = 2; //maybe two?
settings.sampleRate = 32000;
settings.numOutputChannels = 2;
settings.bufferSize = bufferSize;
m_outStream.setup(settings);
}
In the audioOut(), I try to copy from the audioIns’ buffers to the audioOut buffer:
void ofApp::audioOut(ofSoundBuffer& buffer)
{
for (size_t i = 0; i < buffer.getNumFrames(); ++i)
{
auto input1 = m_custom.getStereoBuffers(0);
auto input2 = m_custom.getStereoBuffers(1);
float l = (input1[0][i] + input1[1][i]) * 0.5f;
float r = (input2[0][i] + input2[1][i]) * 0.5f;
buffer.getSample(i, 0) = l * m_outVol;
buffer.getSample(i, 1) = r * m_outVol;
}
}
The result sounds like the amplified input always autotuned to the same pitch- like a flanger effect, even if I set the volume low and point the speakers away from the mics. Can anyone tell me what I’m doing wrong? Should the output be the same soundstream as one of my inputs? N.b. when I change the output sampleRate to 44100 the effect goes from a clearly pitched flange to a noisy sound with a delay-echo. I vaguely remember @roymacdonald saying something about oF’s input and output buffers being connected- is that’s what’s causing this problem?