Воспроизведение синусоиды неизвестное время

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

Но я хочу иметь возможность изменять частоту тона во времени, например, увеличивать ее. Представьте, что я хочу воспроизвести тон A и увеличить его до C с шагом частоты «+5» каждые 3 мс (это действительно просто пример), не хочу иметь свободные места, остановите тон.

Является ли это возможным? Или вы можете мне помочь?


person eCorke    schedule 07.03.2012    source источник


Ответы (2)


Используйте библиотеку NAudio для вывода звука.

Сделать заметки провайдера волны:

class NotesWaveProvider : WaveProvider32
{
    public NotesWaveProvider(Queue<Note> notes)
    {
        this.Notes = notes;
    }
    public readonly Queue<Note> Notes;
    int sample = 0;

    Note NextNote()
    {
        for (; ; )
        {
            if (Notes.Count == 0)
                return null;
            var note = Notes.Peek();
            if (sample < note.Duration.TotalSeconds * WaveFormat.SampleRate)
                return note;

            Notes.Dequeue();
            sample = 0;
        }

    }
    public override int Read(float[] buffer, int offset, int sampleCount)
    {
        int sampleRate = WaveFormat.SampleRate;
        for (int n = 0; n < sampleCount; n++)
        {
            var note = NextNote();
            if (note == null)
                buffer[n + offset] = 0;
            else
                buffer[n + offset] = (float)(note.Amplitude * Math.Sin((2 * Math.PI * sample * note.Frequency) / sampleRate));
            sample++;
        }
        return sampleCount;
    }
}
class Note
{
    public float Frequency;
    public float Amplitude = 1.0f;
    public TimeSpan Duration = TimeSpan.FromMilliseconds(50);

}

начать играть:

WaveOut waveOut;
this.Notes = new Queue<Note>(new[] { new Note { Frequency = 1000 }, new Note { Frequency = 1100 } });
var waveProvider = new NotesWaveProvider(Notes);
waveProvider.SetWaveFormat(16000, 1); // 16kHz mono    

waveOut = new WaveOut();
waveOut.Init(waveProvider);
waveOut.Play();

добавить новые заметки:

void Timer_Tick(...)
{
 if (Notes.Count < 10)
   Notes.Add(new Note{Frecuency = 900});
}

PS этот код является только идеей. для реального использования добавить mt-locking и т. д.

person Serj-Tm    schedule 07.03.2012
comment
Работает очень хорошо, чтобы запустить последовательность заметок. Однако добавление дополнительных нот в очередь после окончания исходной мелодии не работает должным образом. Вы ожидаете, что новая заметка начнется немедленно. Этого можно добиться с помощью приведенного выше кода, вставив сброс счетчика выборки в оператор if (Notes.Count == 0) return null;,.. теперь мой код: if (Notes.Count == 0) { sample=0 ; вернуть ноль; }. В этом случае следующая заметка запустится сразу, даже если она будет запущена через несколько секунд. Кроме того, for (;;) не требуется в NextNote. - person Goodies; 10.07.2017

используйте NAudio и SineWaveProvider32: http://mark-dot-net.blogspot.com/2009/10/playback-of-sine-wave-in-naudio.html

private WaveOut waveOut;

private void button1_Click(object sender, EventArgs e)
{
  StartStopSineWave();
}

private void StartStopSineWave()
{
  if (waveOut == null)
  {
    var sineWaveProvider = new SineWaveProvider32();
    sineWaveProvider.SetWaveFormat(16000, 1); // 16kHz mono
    sineWaveProvider.Frequency = 1000;
    sineWaveProvider.Amplitude = 0.25f;
    waveOut = new WaveOut();
    waveOut.Init(sineWaveProvider);
    waveOut.Play();
  }
  else
  {
    waveOut.Stop();
    waveOut.Dispose();
    waveOut = null;
  }
}
person Serj-Tm    schedule 07.03.2012
comment
спасибо... Я пробовал, но если я пытаюсь изменить частоту, то он ненадолго перестает воспроизводиться. Что мне нужно, так это, возможно, иметь одну функцию для воспроизведения простого массива в цикле, например, один цикл составляет 5 мс (задержка 5 мс для меня достаточно), и в конце каждого цикла проверяйте буферный массив для воспроизведения нового тона... и в еще нить добавить через какое-то время новый тон... - person eCorke; 07.03.2012
comment
но я не знаю, как в нее играть.. и не нашел решения :( - person eCorke; 07.03.2012