Hi,
I’m creating a demo game showcasing my plugin that can imitate voices based on models.
To do that I record and transform the audio using JUCE through this function that runs in its own thread :
void AAudioController::audioDeviceIOCallbackWithContext(const float* const* aInputData, int aNumInputChans, float* const* aOutputData, int aNumOutputChans, int aNumSamples, const juce::AudioIODeviceCallbackContext& context)
{
(void)context;
int index, numActiveInChans = 0, numActiveOutChans = 0;
int numOutsWanted = 2;
const int numInsWanted = 1;
for (index = 0; index < aNumInputChans; ++index)
if (aInputData[index] != 0)
inChans[numActiveInChans++] = (float*)aInputData[index];
while (numActiveInChans < numInsWanted)
inChans[numActiveInChans++] = mEmptyBuffer->getWritePointer(0, 0);
for (index = 0; index < aNumOutputChans; ++index)
if (aOutputData[index] != 0)
outChans[numActiveOutChans++] = aOutputData[index];
index = 0;
while (numActiveOutChans < numOutsWanted)
outChans[numActiveOutChans++] = mEmptyBuffer->getWritePointer(++index, 0);
juce::AudioSampleBuffer input(inChans, juce::jmin(numInsWanted, numActiveInChans), aNumSamples);
juce::AudioSampleBuffer output(outChans, juce::jmin(numOutsWanted, numActiveOutChans), aNumSamples);
for (int channel = juce::jmin(output.getNumChannels(), input.getNumChannels()); --channel >= 0;)
output.copyFrom(channel, 0, input, channel, 0, aNumSamples);
float* leftOChannel = output.getWritePointer(0);
float* rightOChannel = output.getWritePointer(1);
float *leftIChannel = input.getWritePointer(0);
int blockSize = output.getNumSamples();
std::vector<short> bufferIn(blockSize);
std::vector<short> bufferOut(blockSize);
convertFloat32toInt(leftIChannel, blockSize, (char*)bufferIn.data(), false);
if (_handle == -1)
{
}
else
{
std::vector<short> transformedAudio;
InBufferInt.insert(InBufferInt.end(), bufferIn.data(), bufferIn.data() + blockSize);
imi_trans_transform(_handle, (imi_sample_t*)bufferIn.data(), (imi_sample_t*)bufferOut.data());
//fill the outBufferInt with the bufferOut
outBufferInt.insert(outBufferInt.end(), bufferOut.data(), bufferOut.data() + blockSize);
float* bufferOutFloat = new float[blockSize];
convertInttoFloat32((char*)bufferOut.data(), blockSize, bufferOutFloat, false);
// Write bufferOutFloat to the output audio channel2
for (int channel = 0; channel < juce::jmin(output.getNumChannels(), 2); ++channel)
output.copyFrom(channel, 0, bufferOutFloat, blockSize);
// If the number of output channels is greater than 2, clear the additional channels
for (int channel = 2; channel < output.getNumChannels(); ++channel)
output.clear(channel, 0, output.getNumSamples());
}
}
This works fine but it doesn’t generate any sound in the level and just play the audio through the callback of my output devices I’d like to change that by capturing the audio data transformed here :
imi_trans_transform(_handle, (imi_sample_t*)bufferIn.data(), (imi_sample_t*)bufferOut.data());
(so bufferOut)
and playing it in another thread but I don’t really know how to continuously get the buffer data and play it even though I’ve already played sound using a float buffer like that :
Audio::FSoundWavePCMWriter Writer;
Audio::FSampleBuffer TransformedBuffer(AudioBuffer.data(), AudioBuffer.size(), 2, 32000);
TransformedSoundWave = Writer.SynchronouslyWriteSoundWave(TransformedBuffer, nullptr, nullptr);
UGameplayStatics::PlaySound2D(GetWorld(), TransformedSoundWave);
If anyone could give me some help through this project I’d be grateful :))