Come generare suoni in base alla frequenza?

Possibile duplicato:
Creazione di onda sinusoidale o quadrata in C #

Voglio generare suoni. O qualcosa come:

MakeSound(frequency, duration); 

O:

 MakeSound(MyArrayOfSamples); 

Ho trovato qualcosa chiamato: Microsoft.Directx.DirectSound ma ho letto che è stato interrotto. E non ho potuto trovarlo come opzione per un riferimento in Visual Studio (2010). Ho trovato questo link che, secondo quello che ho letto, dovrebbe includerlo, ma sono titubante nell’usare qualcosa dal 2006 in quanto potrebbe non essere più supportato. E questo dice che è per C / C ++ (nonostante diciamo anche: “codice gestito”) e non voglio sprecare settimane cercando di capire come avvolgerlo nel codice gestito, solo per scoprire che non posso farlo. Il link più promettente che ho trovato è WaveFormat ma non sono riuscito a trovare il modo di usarlo.

Non sto chiedendo come ottenere la rappresentazione matematica per l’onda sonora. Né sto chiedendo come riprodurre un file mp3 o simili. Né sto cercando software o wrapper di terze parti. Solo per una soluzione C # / .net per un objective molto specifico.

In entrambi i casi, se non vuoi utilizzare un codice non gestito, dovrai build un WAV per riprodurlo. Tuttavia, di seguito è riportato uno snippet di codice dal blog di Eric Lippert che ti mostrerà come eseguire il rollover del tuo file WAV utilizzando le frequenze.

 namespace Wave { using System; using System.IO; class MainClass { public static void Main() { FileStream stream = new FileStream("test.wav", FileMode.Create); BinaryWriter writer = new BinaryWriter(stream); int RIFF = 0x46464952; int WAVE = 0x45564157; int formatChunkSize = 16; int headerSize = 8; int format = 0x20746D66; short formatType = 1; short tracks = 1; int samplesPerSecond = 44100; short bitsPerSample = 16; short frameSize = (short)(tracks * ((bitsPerSample + 7)/8)); int bytesPerSecond = samplesPerSecond * frameSize; int waveSize = 4; int data = 0x61746164; int samples = 88200 * 4; int dataChunkSize = samples * frameSize; int fileSize = waveSize + headerSize + formatChunkSize + headerSize + dataChunkSize; writer.Write(RIFF); writer.Write(fileSize); writer.Write(WAVE); writer.Write(format); writer.Write(formatChunkSize); writer.Write(formatType); writer.Write(tracks); writer.Write(samplesPerSecond); writer.Write(bytesPerSecond); writer.Write(frameSize); writer.Write(bitsPerSample); writer.Write(data); writer.Write(dataChunkSize); double aNatural = 220.0; double ampl = 10000; double perfect = 1.5; double concert = 1.498307077; double freq = aNatural * perfect; for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI))); writer.Write(s); } freq = aNatural * concert; for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI))); writer.Write(s); } for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI) + Math.Sin(t * freq * perfect * 2.0 * Math.PI))); writer.Write(s); } for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI) + Math.Sin(t * freq * concert * 2.0 * Math.PI))); writer.Write(s); } writer.Close(); stream.Close(); } } } 

aNatural per le tue esigenze, ma nota la variabile aNatural - è una frequenza - proprio come quello che stai cercando.

Ora puoi metterlo in un MemoryStream e poi riprodurlo con SoundPlayer se lo desideri.

Ecco un wrapper attorno alla funzione Beep nel kernel, prendendo una durata e una frequenza. Oggi Beep usa la scheda audio; nei miei giorni ha usato un dispositivo piezo incollato sulla scheda madre.

 using System; using System.Runtime.InteropServices; class BeepSample { [DllImport("kernel32.dll", SetLastError=true)] static extern bool Beep(uint dwFreq, uint dwDuration); static void Main() { Console.WriteLine("Testing PC speaker..."); for (uint i = 100; i <= 20000; i++) { Beep(i, 5); } Console.WriteLine("Testing complete."); } } 

Sulla mia casella Win10 ho bisogno di impostare la durata (ultimo parametro) molto più grande dei 5 ms qui, più fino a 50 ms ma per ottenere qualcosa di ragionevole devo farlo 100 ms.

Oppure usa il metodo Console.Beep (Int32, Int32) se vuoi prendere la strada facile. Questo metodo è stato introdotto in .Net 2.0.