|
|
@@ -28,13 +28,11 @@ struct AudioInterface : Module { |
|
|
|
}; |
|
|
|
enum InputIds { |
|
|
|
AUDIO1_INPUT, |
|
|
|
AUDIO2_INPUT, |
|
|
|
NUM_INPUTS |
|
|
|
NUM_INPUTS = AUDIO1_INPUT + 8 |
|
|
|
}; |
|
|
|
enum OutputIds { |
|
|
|
AUDIO1_OUTPUT, |
|
|
|
AUDIO2_OUTPUT, |
|
|
|
NUM_OUTPUTS |
|
|
|
NUM_OUTPUTS = AUDIO1_OUTPUT + 8 |
|
|
|
}; |
|
|
|
|
|
|
|
PaStream *stream = NULL; |
|
|
@@ -49,14 +47,14 @@ struct AudioInterface : Module { |
|
|
|
std::mutex bufferMutex; |
|
|
|
bool streamRunning; |
|
|
|
|
|
|
|
SampleRateConverter<2> inputSrc; |
|
|
|
SampleRateConverter<2> outputSrc; |
|
|
|
SampleRateConverter<8> inputSrc; |
|
|
|
SampleRateConverter<8> outputSrc; |
|
|
|
|
|
|
|
// in rack's sample rate |
|
|
|
DoubleRingBuffer<Frame<2>, 16> inputBuffer; |
|
|
|
DoubleRingBuffer<Frame<2>, (1<<15)> outputBuffer; |
|
|
|
DoubleRingBuffer<Frame<8>, 16> inputBuffer; |
|
|
|
DoubleRingBuffer<Frame<8>, (1<<15)> outputBuffer; |
|
|
|
// in device's sample rate |
|
|
|
DoubleRingBuffer<Frame<2>, (1<<15)> inputSrcBuffer; |
|
|
|
DoubleRingBuffer<Frame<8>, (1<<15)> inputSrcBuffer; |
|
|
|
|
|
|
|
AudioInterface(); |
|
|
|
~AudioInterface(); |
|
|
@@ -113,9 +111,10 @@ void AudioInterface::step() { |
|
|
|
// Get input and pass it through the sample rate converter |
|
|
|
if (numOutputs > 0) { |
|
|
|
if (!inputBuffer.full()) { |
|
|
|
Frame<2> f; |
|
|
|
f.samples[0] = getf(inputs[AUDIO1_INPUT]) / 5.0; |
|
|
|
f.samples[1] = getf(inputs[AUDIO2_INPUT]) / 5.0; |
|
|
|
Frame<8> f; |
|
|
|
for (int i = 0; i < 8; i++) { |
|
|
|
f.samples[i] = getf(inputs[AUDIO1_INPUT + i]) / 5.0; |
|
|
|
} |
|
|
|
inputBuffer.push(f); |
|
|
|
} |
|
|
|
|
|
|
@@ -133,9 +132,10 @@ void AudioInterface::step() { |
|
|
|
|
|
|
|
// Set output |
|
|
|
if (!outputBuffer.empty()) { |
|
|
|
Frame<2> f = outputBuffer.shift(); |
|
|
|
setf(outputs[AUDIO1_OUTPUT], 5.0 * f.samples[0]); |
|
|
|
setf(outputs[AUDIO2_OUTPUT], 5.0 * f.samples[1]); |
|
|
|
Frame<8> f = outputBuffer.shift(); |
|
|
|
for (int i = 0; i < 8; i++) { |
|
|
|
setf(outputs[AUDIO1_OUTPUT + i], 5.0 * f.samples[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -152,10 +152,10 @@ void AudioInterface::stepStream(const float *input, float *output, int numFrames |
|
|
|
std::lock_guard<std::mutex> lock(bufferMutex); |
|
|
|
// input stream -> output buffer |
|
|
|
if (numInputs > 0) { |
|
|
|
Frame<2> inputFrames[numFrames]; |
|
|
|
Frame<8> inputFrames[numFrames]; |
|
|
|
for (int i = 0; i < numFrames; i++) { |
|
|
|
for (int c = 0; c < 2; c++) { |
|
|
|
inputFrames[i].samples[c] = (numInputs > c) ? input[i*numInputs + c] : 0.0; |
|
|
|
for (int c = 0; c < 8; c++) { |
|
|
|
inputFrames[i].samples[c] = (c < numInputs) ? input[i*numInputs + c] : 0.0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -172,9 +172,9 @@ void AudioInterface::stepStream(const float *input, float *output, int numFrames |
|
|
|
for (int i = 0; i < numFrames; i++) { |
|
|
|
if (inputSrcBuffer.empty()) |
|
|
|
break; |
|
|
|
Frame<2> f = inputSrcBuffer.shift(); |
|
|
|
Frame<8> f = inputSrcBuffer.shift(); |
|
|
|
for (int c = 0; c < numOutputs; c++) { |
|
|
|
output[i*numOutputs + c] = f.samples[c]; |
|
|
|
output[i*numOutputs + c] = (c < 8) ? f.samples[c] : 0.0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -400,7 +400,7 @@ struct BlockSizeChoice : ChoiceButton { |
|
|
|
AudioInterfaceWidget::AudioInterfaceWidget() { |
|
|
|
AudioInterface *module = new AudioInterface(); |
|
|
|
setModule(module); |
|
|
|
box.size = Vec(15*8, 380); |
|
|
|
box.size = Vec(15*12, 380); |
|
|
|
|
|
|
|
{ |
|
|
|
Panel *panel = new LightPanel(); |
|
|
@@ -409,21 +409,23 @@ AudioInterfaceWidget::AudioInterfaceWidget() { |
|
|
|
} |
|
|
|
|
|
|
|
float margin = 5; |
|
|
|
float labelHeight = 15; |
|
|
|
float yPos = margin; |
|
|
|
float xPos; |
|
|
|
|
|
|
|
{ |
|
|
|
Label *label = new Label(); |
|
|
|
label->box.pos = Vec(margin, yPos); |
|
|
|
label->text = "Audio device"; |
|
|
|
addChild(label); |
|
|
|
yPos += label->box.size.y + margin; |
|
|
|
yPos += labelHeight + margin; |
|
|
|
|
|
|
|
AudioChoice *choice = new AudioChoice(); |
|
|
|
choice->audioInterface = dynamic_cast<AudioInterface*>(module); |
|
|
|
choice->box.pos = Vec(margin, yPos); |
|
|
|
choice->box.size.x = box.size.x - 10; |
|
|
|
addChild(choice); |
|
|
|
yPos += choice->box.size.y + 2*margin; |
|
|
|
yPos += choice->box.size.y + margin; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
@@ -431,14 +433,14 @@ AudioInterfaceWidget::AudioInterfaceWidget() { |
|
|
|
label->box.pos = Vec(margin, yPos); |
|
|
|
label->text = "Sample rate"; |
|
|
|
addChild(label); |
|
|
|
yPos += label->box.size.y + margin; |
|
|
|
yPos += labelHeight + margin; |
|
|
|
|
|
|
|
SampleRateChoice *choice = new SampleRateChoice(); |
|
|
|
choice->audioInterface = dynamic_cast<AudioInterface*>(module); |
|
|
|
choice->box.pos = Vec(margin, yPos); |
|
|
|
choice->box.size.x = box.size.x - 10; |
|
|
|
addChild(choice); |
|
|
|
yPos += choice->box.size.y + 2*margin; |
|
|
|
yPos += choice->box.size.y + margin; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
@@ -446,14 +448,14 @@ AudioInterfaceWidget::AudioInterfaceWidget() { |
|
|
|
label->box.pos = Vec(margin, yPos); |
|
|
|
label->text = "Block size"; |
|
|
|
addChild(label); |
|
|
|
yPos += label->box.size.y + margin; |
|
|
|
yPos += labelHeight + margin; |
|
|
|
|
|
|
|
BlockSizeChoice *choice = new BlockSizeChoice(); |
|
|
|
choice->audioInterface = dynamic_cast<AudioInterface*>(module); |
|
|
|
choice->box.pos = Vec(margin, yPos); |
|
|
|
choice->box.size.x = box.size.x - 10; |
|
|
|
addChild(choice); |
|
|
|
yPos += choice->box.size.y + 2*margin; |
|
|
|
yPos += choice->box.size.y + margin; |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
@@ -461,12 +463,33 @@ AudioInterfaceWidget::AudioInterfaceWidget() { |
|
|
|
label->box.pos = Vec(margin, yPos); |
|
|
|
label->text = "Outputs"; |
|
|
|
addChild(label); |
|
|
|
yPos += label->box.size.y + margin; |
|
|
|
yPos += labelHeight + margin; |
|
|
|
} |
|
|
|
|
|
|
|
yPos += 5; |
|
|
|
xPos = 10; |
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
addInput(createInput<PJ3410Port>(Vec(xPos, yPos), module, AudioInterface::AUDIO1_INPUT + i)); |
|
|
|
Label *label = new Label(); |
|
|
|
label->box.pos = Vec(xPos + 4, yPos + 28); |
|
|
|
label->text = stringf("%d", i); |
|
|
|
addChild(label); |
|
|
|
|
|
|
|
xPos += 37 + margin; |
|
|
|
} |
|
|
|
yPos += 35 + margin; |
|
|
|
|
|
|
|
yPos += 5; |
|
|
|
addInput(createInput<PJ3410Port>(Vec(20, yPos), module, AudioInterface::AUDIO1_INPUT)); |
|
|
|
addInput(createInput<PJ3410Port>(Vec(70, yPos), module, AudioInterface::AUDIO2_INPUT)); |
|
|
|
xPos = 10; |
|
|
|
for (int i = 4; i < 8; i++) { |
|
|
|
addInput(createInput<PJ3410Port>(Vec(xPos, yPos), module, AudioInterface::AUDIO1_INPUT + i)); |
|
|
|
Label *label = new Label(); |
|
|
|
label->box.pos = Vec(xPos + 4, yPos + 28); |
|
|
|
label->text = stringf("%d", i); |
|
|
|
addChild(label); |
|
|
|
|
|
|
|
xPos += 37 + margin; |
|
|
|
} |
|
|
|
yPos += 35 + margin; |
|
|
|
|
|
|
|
{ |
|
|
@@ -474,11 +497,32 @@ AudioInterfaceWidget::AudioInterfaceWidget() { |
|
|
|
label->box.pos = Vec(margin, yPos); |
|
|
|
label->text = "Inputs"; |
|
|
|
addChild(label); |
|
|
|
yPos += label->box.size.y + margin; |
|
|
|
yPos += labelHeight + margin; |
|
|
|
} |
|
|
|
|
|
|
|
yPos += 5; |
|
|
|
xPos = 10; |
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
addOutput(createOutput<PJ3410Port>(Vec(xPos, yPos), module, AudioInterface::AUDIO1_OUTPUT + i)); |
|
|
|
Label *label = new Label(); |
|
|
|
label->box.pos = Vec(xPos + 4, yPos + 28); |
|
|
|
label->text = stringf("%d", i); |
|
|
|
addChild(label); |
|
|
|
|
|
|
|
xPos += 37 + margin; |
|
|
|
} |
|
|
|
yPos += 35 + margin; |
|
|
|
|
|
|
|
yPos += 5; |
|
|
|
addOutput(createOutput<PJ3410Port>(Vec(20, yPos), module, AudioInterface::AUDIO1_OUTPUT)); |
|
|
|
addOutput(createOutput<PJ3410Port>(Vec(70, yPos), module, AudioInterface::AUDIO2_OUTPUT)); |
|
|
|
xPos = 10; |
|
|
|
for (int i = 4; i < 8; i++) { |
|
|
|
addOutput(createOutput<PJ3410Port>(Vec(xPos, yPos), module, AudioInterface::AUDIO1_OUTPUT + i)); |
|
|
|
Label *label = new Label(); |
|
|
|
label->box.pos = Vec(xPos + 4, yPos + 28); |
|
|
|
label->text = stringf("%d", i); |
|
|
|
addChild(label); |
|
|
|
|
|
|
|
xPos += 37 + margin; |
|
|
|
} |
|
|
|
yPos += 35 + margin; |
|
|
|
} |