Воспроизведение файлов WAV одновременно в режиме реального времени с использованием Java
У меня возникли трудности с использованием JSyn для одновременных WAV в реальном времени.
Я пытаюсь создать собственную клавиатуру с настроенными тонами, и я записал все мелодии в формате WAV.
Я сослался на файл PlaySample.java JSyn и попытался использовать тот же метод для клавиатуры, но проблема в том, что каждый семпл должен воспроизводиться сразу после нажатия клавиши из графического интерфейса, но VariableRateDataReader предоставляет dataQueue для воспроизведения семпла. Таким образом, если какой-либо сэмпл уже воспроизводится, и одновременно нажимается какая-то другая клавиша, другой файл сэмпла будет воспроизведен после первого, так что это приведет к задержке, и первый сэмпл должен продолжить воспроизведение даже после нажатия некоторых других клавиш.
Demo.java
public class Demo {
private Synthesizer synth;
private VariableRateDataReader samplePlayer;
private LineOut lineOut;
private void test() {
synth = JSyn.createSynthesizer();
FloatSample cSharpSample;
FloatSample dSharpSample;
FloatSample eSample;
FloatSample dSample;
FloatSample bSample;
FloatSample fSharpSample;
FloatSample gSharpSample;
try {
lineOut = new LineOut();
synth.add(lineOut);
SampleLoader.setJavaSoundPreferred(false);
cSharpSample = SampleLoader.loadFloatSample(getClass().getResourceAsStream("/resources/wav/octapad/c#.wav"));
dSharpSample = SampleLoader.loadFloatSample(getClass().getResourceAsStream("/resources/wav/octapad/d#.wav"));
eSample = SampleLoader.loadFloatSample(getClass().getResourceAsStream("/resources/wav/octapad/e.wav"));
bSample = SampleLoader.loadFloatSample(getClass().getResourceAsStream("/resources/wav/octapad/b.wav"));
fSharpSample = SampleLoader.loadFloatSample(getClass().getResourceAsStream("/resources/wav/octapad/f#.wav"));
gSharpSample = SampleLoader.loadFloatSample(getClass().getResourceAsStream("/resources/wav/octapad/g#.wav"));
synth.add(samplePlayer = new VariableRateStereoReader());
samplePlayer.output.connect(0, lineOut.input, 0);
samplePlayer.output.connect(1, lineOut.input, 1);
synth.start();
samplePlayer.rate.set(cSharpSample.getFrameRate());
lineOut.start();
double gap = 100;
// shouldplay e c# b g#, only g# is being played
samplePlayer.dataQueue.queueOn(eSample);
samplePlayer.dataQueue.queueOn(cSharpSample);
samplePlayer.dataQueue.queueOn(bSample);
samplePlayer.dataQueue.queueOn(gSharpSample);
do {
synth.sleepFor(20.0);
} while (samplePlayer.dataQueue.hasMore());
synth.sleepFor(0.5);
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
synth.stop();
}
public static void main(String[] args) {
new Demo().test();
}
}
Так что вопрос в том; Есть ли какой-либо API, доступный через JSyn, с помощью которого я могу одновременно воспроизводить файлы WAV, не останавливая сэмпл, который в данный момент воспроизводится? И я не хочу использовать SOX или любой другой метод для воспроизведения файлов WAV, это должно быть сделано только с использованием Java.
1 ответ
Если вы хотите воспроизвести 8 сэмплов одновременно, вам нужно 8 блоков VariableRateDataReader. Подключите их все к LineOut, и они автоматически смешаются.
Вы можете иметь один VariableRateDataReader для каждого образца. Или вы можете иметь только несколько считывателей и динамически назначать считыватель для образца по мере необходимости.
Есть встроенные классы, которые могут помочь. JSyn VoiceAllocator назначит объекты UnitVoice. Каждый UnitVoice может содержать VariableRateDataReader.