2012-03-07 9 views
6

하루 종일 "무한대"시간 동안 단순한 sin 파형을 재생하기 위해 튜토리얼이나 코드 조각을 찾고있었습니다. 나는 그것이 조금 미친 소리라는 것을 알고있다.uknown time을위한 사인파 재생

하지만 시간이 지나면 소리의 빈도를 변경할 수 있기를 원합니다. 예를 들어 늘리십시오. 톤 A를 연주하고, "+5"frenquency 단계를 3ms마다 증가시키고 싶다고 상상해보십시오 (실제로는 단지 예입니다). 자유로운 장소를 원하지 않고, 음을 멈추십시오.

가능합니까? 아니면 나를 도울 수 있니?

답변

5

사용 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- 잠금 등

+0

노트의 순서를 시작하는 아주 좋은 작품. 그러나 , 초기 "멜로디"가 끝난 후 대기열에 더 많은 음을 추가하면 제대로 작동하지 않습니다. 새 음표가 즉시 시작되기를 기대합니다. 위 코드를 사용하면 명령문에 샘플 카운터를 재설정하여 삽입 할 수 있습니다 if (이 경우, 다음 노트는 즉시 시작됩니다. (Notes.Count == 0) {sample = 0; return null;} 몇 초 후에 시작되며, for (;;)는 NextNote에서 필요하지 않습니다. – Goodies

1

사용 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; 
    } 
} 
+0

감사 ... 나는 주파수를 변경하려고하는 경우 그것을 시도하고 짧은 시간 동안 재생을 중지합니다. 내가 필요로하는 것은 어쩌면 간단한 배열을 재생하기위한 하나의 함수를 갖는 것일 수 있습니다. 예를 들어 한주기가 5ms (5ms 지연은 충분합니다)이고 각주기의 끝에는 새로운 "음색"을 재생할 bufferArray를 확인하는 것입니다. 그리고 다른 스레드에서 시간이 조금 후에 새로운 "음색"을 추가 ... – eCorke

+0

하지만 나는 그것을 어떻게 연주 해야할지 모르겠어 .. 그리고 어떤 해결책을 발견하지 못했습니다 : ( – eCorke