NAudio воспроизводит синусоидальный сигнал в течение x миллисекунд, используя C # - PullRequest
6 голосов
/ 30 марта 2011

Я использую NAudio для воспроизведения синусоиды с заданной частотой, как в сообщении в блоге Воспроизведение синусоидальной волны в NAudio . Я просто хочу, чтобы звук воспроизводился () в течение x миллисекунд, а затем останавливался.

Я попробовал нить. Сплю, но звук сразу останавливается. Я пробовал таймер, но при удалении WaveOut возникает исключение между потоками.

Я попробовал этот код, но при вызове звукового сигнала программа зависает.

public class Beep
{
    public Beep(int freq, int ms)
    {
        SineWaveProvider32 sineWaveProvider = new SineWaveProvider32();
        sineWaveProvider.Amplitude = 0.25f;
        sineWaveProvider.Frequency = freq;

        NAudio.Wave.WaveOut waveOut = new NAudio.Wave.WaveOut(WaveCallbackInfo.FunctionCallback());
        waveOut.Init(sineWaveProvider);
        waveOut.Play();
        Thread.Sleep(ms);
        waveOut.Stop();
        waveOut.Dispose();
    }
}

public class SineWaveProvider32 : NAudio.Wave.WaveProvider32
{
    int sample;

    public SineWaveProvider32()
    {
        Frequency = 1000;
        Amplitude = 0.25f; // Let's not hurt our ears
    }

    public float Frequency { get; set; }
    public float Amplitude { get; set; }

    public override int Read(float[] buffer, int offset, int sampleCount)
    {
        int sampleRate = WaveFormat.SampleRate;
        for (int n = 0; n < sampleCount; n++)
        {
            buffer[n + offset] = (float)(Amplitude * Math.Sin((2 * Math.PI * sample * Frequency) / sampleRate));
            sample++;
            if (sample >= sampleRate)
                sample = 0;
        }
   }

Ответы [ 2 ]

4 голосов
/ 14 апреля 2011

Класс SineWaveProvider32 не должен предоставлять аудио на неопределенный срок. Если вы хотите, чтобы звуковой сигнал имел максимальную длительность в секунду (скажем), то для моно 44,1 кГц вам необходимо предоставить 44 100 сэмплов. Метод Read должен возвращать 0, если у него больше нет данных для предоставления.

Чтобы ваш поток GUI не блокировался, вам нужно избавиться от Thread.Sleep, waveOut.Stop и Dispose и просто начать воспроизводить аудио (вы можете найти обратные вызовы окон более надежными, чем функции).

Затем, когда аудио закончится, вы можете закрыть и очистить объект WaveOut.

0 голосов
/ 30 марта 2011

Ознакомьтесь с сообщением в блоге Передача переменных в новую тему в C # о том, как передавать переменные в другую тему.

Я думаю, что вы хотите сделать что-то вроде создания потока, воспроизводящего ваш звук, создания таймера и запуска потока. Когда таймер истекает, убейте поток, а когда поток закроется, сделайте всю очистку.

...