2012-04-04 13 views
3

Ich habe ein Problem, das auf den ersten Blick sieht wirklich einfach aus, aber ich habe große Probleme zu lösen.Wiedergabe von Doppel-Array

Ich habe 2 Doppel-Arrays (linker und rechter Kanal), die Daten enthalten, die von einem DAQ bei 350 kHz abgetastet wurden, die ich auf 44,1 KHz herunterkonvertiert habe.

Alles, was ich tun möchte, ist, diese 2 Arrays zu nehmen und sie zu spielen, aber es scheint, als ob es eine Vielzahl von Optionen für die Ausgabe von Ton gibt, dh directx, NAudio etc, also hoffe ich, dass da jemand da draußen sein könnte kann mich beraten, was der beste Weg ist, um dies zu tun und vielleicht zeigen Sie mir in die richtige Richtung!

Vielen Dank im Voraus für jeden Hinweis - es wird sehr geschätzt werden.

Dave

Antwort

3

NAudio ist eine Option, die ich gehört habe, die Menschen ein paar Mal erwähnt (wie man auch tat). Ich weiß, dass es eine Open-Source-Bibliothek von Drittanbietern ist. Vielleicht möchten Sie sich das ansehen.

Leider scheint mir, dass DirectX auf dem Weg nach draußen ist und MS hat ihren Schub auf ein paar verschiedene Dinge im Laufe der Jahre geändert, und jetzt scheint es, dass sie auf Menschen drängen, XNA zu verwenden ist wirklich ein gesamtes Framework, das, wenn Sie Projekte in XNA erstellen, es unter Windows in einer Desktopumgebung oder Xbox 360 oder Windows Phone ausführen kann. Für mich ist das Windows Phone keine große Sache, da es scheint, dass MS kein großer Spieler in der mobilen Welt ist, aber eine App, die auf Xbox funktioniert, gefällt mir. Aber ich habe einige bessere Funktionen im XNA-Framework/der XNA-Architektur gesehen, die im regulären .NET-Framework fehlen, einschließlich Videowiedergabe und Audiowiedergabe. Ich weiß nicht viel Details darüber hinaus, da ich noch nicht in XNA (noch) in Entwicklung gegangen bin.

Sie können sie auch direkt in .NET mit System.Media.SoundPlayer ohne 3rd-Party-Bibliothek spielen.

Ich fand den folgenden Code, der eine einfache Sinuswelle spielt, mit ihm. Er erzeugt die Sound-Samples und gibt sie dann an eine MemoryStream, die dann mit dem SoundPlayer abgespielt wird. Der SoundPlayer selbst nimmt einen im WAV-Format formatierten Stream, von dem ich weiß, dass er Stereoklang wiedergeben kann, aber ich brauche keinen Stereoton, also habe ich nicht untersucht, wie ich das zum WAV-Dateiformat hinzufügen kann. Was ich so sehr daran mag ist, dass es keine DLLs von Drittanbietern benötigt. Wenn diese Methode ist nützlich für Sie, dann ist es hier:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Windows.Forms; 

public static void PlayBeep(UInt16 frequency, int msDuration, UInt16 volume = 16383) 
{ 
    var mStrm = new MemoryStream(); 
    BinaryWriter writer = new BinaryWriter(mStrm); 

    const double TAU = 2 * Math.PI; 
    int formatChunkSize = 16; 
    int headerSize = 8; 
    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 samples = (int)((decimal)samplesPerSecond * msDuration/1000); 
    int dataChunkSize = samples * frameSize; 
    int fileSize = waveSize + headerSize + formatChunkSize + headerSize + dataChunkSize; 
    // var encoding = new System.Text.UTF8Encoding(); 
    writer.Write(0x46464952); // = encoding.GetBytes("RIFF") 
    writer.Write(fileSize); 
    writer.Write(0x45564157); // = encoding.GetBytes("WAVE") 
    writer.Write(0x20746D66); // = encoding.GetBytes("fmt ") 
    writer.Write(formatChunkSize); 
    writer.Write(formatType); 
    writer.Write(tracks); 
    writer.Write(samplesPerSecond); 
    writer.Write(bytesPerSecond); 
    writer.Write(frameSize); 
    writer.Write(bitsPerSample); 
    writer.Write(0x61746164); // = encoding.GetBytes("data") 
    writer.Write(dataChunkSize); 
    { 
     double theta = frequency * TAU/(double)samplesPerSecond; 
     // 'volume' is UInt16 with range 0 thru Uint16.MaxValue (= 65 535) 
     // we need 'amp' to have the range of 0 thru Int16.MaxValue (= 32 767) 
     double amp = volume >> 2; // so we simply set amp = volume/2 
     for (int step = 0; step < samples; step++) 
     { 
      short s = (short)(amp * Math.Sin(theta * (double)step)); 
      writer.Write(s); 
     } 
    } 

    mStrm.Seek(0, SeekOrigin.Begin); 
    new System.Media.SoundPlayer(mStrm).Play(); 
    writer.Close(); 
    mStrm.Close(); 
} // public static void PlayBeep(UInt16 frequency, int msDuration, UInt16 volume = 16383) 

Natürlich, wenn Sie mit dieser letzten Option zu gehen, müssen Sie herausfinden, wie Stereo-Sound in das WAV-Format zu formatieren und in diesen Blick selbst (oder fragen Sie danach). Glückliche Kodierung!

+0

Bitte stimmen Sie ab, wenn dies für Sie nützlich ist. (Wie du sehen kannst, ist mein Ruf ziemlich niedrig und ich bin selbst ein Neuling für StackOverflow. Ich möchte also Reputationspunkte aufbauen. Danke!) – Edward

+0

Ich glaube, dass die Variable 'tracks' im Code die 'Channels' ist wo wäre es 2 für Stereo-Sound. http://www.sonicspot.com/guide/wavefiles.html ist eine nette Seite für Informationen über das WAV-Dateiformat. – Edward