Вот возможный подход, который следует рассмотреть.
Во-первых, напишите свой собственный микрофонный считыватель. (Существуют учебные пособия о том, как это сделать.) Затем переупакуйте эти данные в виде двух параллельных строк, которые могут читать другие приложения.
Другой подход - проверить, имеет ли какое-либо приложение какую-либо возможность «сквозной передачи» включен.
РЕДАКТИРОВАТЬ: добавлено для уточнения
Этот Java пример кода утилиты записи звука открывает TargetDataLine
микрофону и сохраняет данные с него в массив (строки 69, 70). Вместо того, чтобы хранить данные в массиве, я предлагаю вам создать два объекта SourceDataLine
и записать данные для каждого из них.
recordBytes = new ByteArrayOutputStream();
secondStreamBytes = new ByteArrayOutputStream();
isRunning = true;
while (isRunning) {
bytesRead = audioLine.read(buffer, 0, buffer.length);
recordBytes.write(buffer, 0, bytesRead);
secondStreamBytes.write(buffer, 0, bytesRead);
}
Надеюсь, не составит труда понять, как чтобы настроить две программы для чтения из созданных строк, а не из линии микрофона. Я не могу дать указания, как это сделать.
РЕДАКТИРОВАТЬ 2: Я хочу, чтобы sh другие люди присоединились к нему. Я немного не в себе, делая что-нибудь необычное с потоками. И код, который вы даете, настолько минимален, что я до сих пор не понимаю, что происходит или как что-то соединяется.
FWTW: (1) Данные, которые вы добавляете в "series1", являются потоковыми данными? Если да, можете ли вы добавить строку в этот for
l oop и записать те же данные в поток, используемый другим классом? (Это был бы способ использования данных микрофона «последовательно», а не «параллельно».)
(2) Потоки данных часто включают код, который блокируется или выполняется с различной скоростью из-за непредсказуемости способ переключения процессора между задачами. Поэтому, если вы напишете «разделитель» (как я пытался проиллюстрировать, изменив код чтения микрофона, который я связал ранее), может возникнуть ситуация, когда код будет работать только с такой скоростью, как более медленное из двух «разделений» при заданном момент. Возможно, вам потребуется включить какую-то буферизацию и использовать отдельные потоки для двух получателей данных с микрофона.
Недавно я написал свой первый код буферизации для ситуации, когда линия считывания микрофона отправляет поток на функция микширования звука в другом потоке. Я написал это всего несколько недель go, и это первый раз, когда я имел дело с попыткой запустить поток через потоки барьера потока, поэтому я не знаю, является ли идея, которую я придумал, лучший способ сделать это Такие вещи. Но ему удается поддерживать постоянный поток от микрофона к микшеру без выпадений и потерь.
Считывающее устройство микрофона считывает буфер данных, а затем добавляет этот byte[]
буфер в ConcurrentLinkedQueue<Byte[]>
.
Из другого потока код микширования звука опрашивает ConcurrentLinkedQueue
на предмет данных.
Я немного поэкспериментировал, и в настоящее время размер буфера byte [] равен 512 байтам, а ConcurrentLinkedQueue
настроен на хранение до 12 «буферов», прежде чем он начнет отбрасывать самые старые буферы (структура это FIFO). Кажется, этих небольших буферов достаточно, чтобы приспособиться, когда код обработки микрофона временно опережает микшер.
В ConcurrentLinkedQueue
есть встроенные средства, позволяющие добавлять и опрашивать одновременно из двух потоков без создания исключения. Я не могу сказать, нужно ли вам это написать, чтобы помочь с раздачей рук, и какой может быть лучший размер буфера. Может быть, лучше будет иметь буфер гораздо большего размера с меньшим количеством буферов, содержащихся в Очереди. это лучшее, что я могу сделать, учитывая мой ограниченный опыт в этом. Надеюсь, у вас получится что-нибудь придумать.