2013-04-18 16 views
10

Ich mache gerade ein sehr sehr wichtiges Schulprojekt. Ich muss die Informationen einer WAVE-Datei in C/C++ extrahieren und die Informationen verwenden, um den LPC eines Sprachsignals zu erhalten. Aber um das zu tun, muss ich das Signal vorverarbeiten, wie z. B. Nulldurchgang und Energieanalyse. Was bedeutet, dass ich das Zeichen und einen echten Wert brauche. Das Problem ist, dass ich nicht weiß, wie man nützliche Informationen und das richtige Format dafür erhält. Ich habe bereits jedes einzelne Feld in der Datei gelesen, aber ich bin mir nicht sicher, ob ich es richtig mache. Vorschläge, bitte?Lesen und Verarbeiten von WAV-Dateidaten in C/C++

Dies ist die Art, wie ich die Datei zur Zeit lesen:

Readi = fread (& bps, 1, 2, Audio); printf ("Bits pro Beispiel =% d \ n", bps);

Vielen Dank im Voraus.

+3

http://www.mega-nerd.com/libsndfile/ http://ccrma.stanford.edu/software/snd/sndlib/ sind zwei Bibliotheken, die Ihnen bei der Arbeit mit WAVs helfen können. – Patashu

Antwort

15

Meine erste Empfehlung wäre, eine Art von Bibliothek zu verwenden, um Ihnen zu helfen. Die meisten Sound-Lösungen scheinen übertrieben zu sein, daher sollte eine einfache Bibliothek (wie die im Kommentar Ihrer Frage empfohlene, libsndfile) den Trick machen.

Wenn Sie nur wissen wollen, wie man WAV-Dateien liest, damit Sie Ihre eigenen schreiben können (da Ihre Schule die Nase rümpfen wird, wenn Sie eine Bibliothek wie jede andere normale Person verwenden), erhalten Sie eine schnelle Google-Suche alle Informationen, die Sie benötigen plus some people who have already wrote many tutorials on reading the .wav format.

Wenn Sie es immer noch nicht bekommen, hier ist ein Teil meines eigenen Codes, wo ich die Header und alle anderen Teile der WAV/RIFF-Datei lesen, bis ich auf den Datenblock komme. Es basiert exclusively off the WAV Format Specification. Das Extrahieren der eigentlichen Sound-Daten ist nicht sehr schwierig: Sie können es entweder roh lesen und es roh verwenden oder eine Konvertierung in ein Format durchführen, mit dem Sie intern mehr Komfort haben würden (32-Bit-PCM unkomprimierte Daten oder so).

Wenn Sie den folgenden Code betrachten, ersetzen Sie reader.Read...(...) durch äquivalente fread Aufrufe für Integer-Werte und Byte-Größen des angegebenen Typs. WavChunks ist eine Enumeration, die die Little-Endian-Werte des IDs innerhalb einer WAV-Datei chunk ist, und das format Variable ist einer der Typen der Wav-Format-Typen, die im WAV-Dateiformat enthalten sein können:

enum class WavChunks { 
    RiffHeader = 0x46464952, 
    WavRiff = 0x54651475, 
    Format = 0x020746d66, 
    LabeledText = 0x478747C6, 
    Instrumentation = 0x478747C6, 
    Sample = 0x6C706D73, 
    Fact = 0x47361666, 
    Data = 0x61746164, 
    Junk = 0x4b4e554a, 
}; 

enum class WavFormat { 
    PulseCodeModulation = 0x01, 
    IEEEFloatingPoint = 0x03, 
    ALaw = 0x06, 
    MuLaw = 0x07, 
    IMAADPCM = 0x11, 
    YamahaITUG723ADPCM = 0x16, 
    GSM610 = 0x31, 
    ITUG721ADPCM = 0x40, 
    MPEG = 0x50, 
    Extensible = 0xFFFE 
}; 

int32 chunkid = 0; 
bool datachunk = false; 
while (!datachunk) { 
    chunkid = reader.ReadInt32(); 
    switch ((WavChunks)chunkid) { 
    case WavChunks::Format: 
     formatsize = reader.ReadInt32(); 
     format = (WavFormat)reader.ReadInt16(); 
     channels = (Channels)reader.ReadInt16(); 
     channelcount = (int)channels; 
     samplerate = reader.ReadInt32(); 
     bitspersecond = reader.ReadInt32(); 
     formatblockalign = reader.ReadInt16(); 
     bitdepth = reader.ReadInt16(); 
     if (formatsize == 18) { 
      int32 extradata = reader.ReadInt16(); 
      reader.Seek(extradata, SeekOrigin::Current); 
     } 
     break; 
    case WavChunks::RiffHeader: 
     headerid = chunkid; 
     memsize = reader.ReadInt32(); 
     riffstyle = reader.ReadInt32(); 
     break; 
    case WavChunks::Data: 
     datachunk = true; 
     datasize = reader.ReadInt32(); 
     break; 
    default: 
     int32 skipsize = reader.ReadInt32(); 
     reader.Seek(skipsize, SeekOrigin::Current); 
     break; 
    } 
} 
+1

Warum wird RIFF rückwärts in das Hex geschrieben? Ich weiß von Little/Big Endian, aber alle Hex-Editoren, die ich benutzt habe, zeigen es als RIFF anstelle von FFIR, machen sie hinter den Kulissen eine seltsame Konvertierung oder läuft etwas anderes? – MarcusJ

+0

Ich glaube @MarcusJ ist richtig sollte RIFF lesen, hier ist eine Beschreibung des Wave-Formats http://soundfile.sapp.org/doc/WaveFormat/ also ich glaube, es sollte RiffHeader = 0x52494646 sein, wie das Format angibt, es ist ein großes -Endian-Feld – alexm

Verwandte Themen