У меня есть проект С#, который воспроизводит код Морзе для RSS-каналов. Я пишу его с помощью Managed DirectX, только чтобы обнаружить, что Managed DirectX устарел и устарел. Задача, которую я имею, - играть в чистые синусоидальные всплески, чередующиеся с периодами молчания (код), которые точно рассчитаны по их длительности. Мне нужно иметь возможность вызывать функцию, которая воспроизводит чистый тон в течение многих миллисекунд, затем Thread.Sleep(), затем воспроизводит другой и т.д. В самом быстром случае тона и пространства могут быть короткими, как 40 мс.
Он отлично работает в Managed DirectX. Чтобы получить точно настроенный тон, я создаю 1 сек. синусоидальной волны во вторичный буфер, а затем для воспроизведения тона определенной продолжительности, которую я ищу вперед в течение х миллисекунд в конце буфера, тогда играйте.
Я пробовал System.Media.SoundPlayer. Это проигравший [edit - см. Мой ответ ниже], потому что вам нужно играть(), Sleep(), а затем Stop() для произвольной длины тона. В результате получается слишком длинный тон, зависящий от нагрузки процессора. Для фактического прекращения тона требуется неопределенное количество времени.
Затем я приступил к длительной попытке использовать NAudio 1.3. Я закончил с резидентным потоком памяти, предоставляющим данные тона, и снова искал вперед, оставляя желаемую длину тона, оставшегося в потоке, а затем играл. Это некоторое время работало нормально в классе DirectSoundOut (см. Ниже), но класс WaveOut быстро умирает с внутренним утверждением, говорящим, что буферы все еще находятся в очереди, несмотря на PlayerStopped = true. Это странно, так как я играю до конца, а затем ожидаю того же времени между окончанием тона и началом следующего. Вы могли бы подумать, что через 80 мс после начала воспроизведения мелодии в 40 мс он не будет иметь буферы в очереди.
DirectSoundOut работает хорошо, но его проблема в том, что для каждого тонального всплеска Play() он отжимает отдельный поток. В конце концов (5 минут или около того) он просто перестает работать. Вы можете видеть поток после потока после выхода потока в окне вывода при запуске проекта в VS2008 IDE. Я не создаю новые объекты во время игры, я просто ищу() поток тембра, затем снова и снова звоню в Play(), поэтому я не думаю, что это проблема с потерянными буферами/тем, что накапливается до тех пор, пока оно не задохнется.
У меня нет терпения по этому поводу, поэтому я прошу в надежде, что кто-то здесь столкнулся с аналогичным требованием и может направить меня в направлении с вероятным решением.