2013-04-18 12 views
10

Obecnie robię bardzo ważny projekt szkolny. Muszę wyodrębnić informacje z pliku WAVE w C/C++ i użyć tych informacji, aby uzyskać LPC sygnału głosowego. Jednak, aby to zrobić, muszę wykonać pewne wstępne przetwarzanie sygnału, takie jak między innymi przepuszczanie zer i analiza energii. Co oznacza, że ​​potrzebuję znaku i prawdziwej wartości. Problem polega na tym, że nie wiem, jak uzyskać użyteczne informacje i ich prawidłowy format. Przeczytałem już wszystkie pola w pliku, ale nie jestem pewien, czy robię to dobrze. Sugestie, proszę?Odczytywanie i przetwarzanie danych pliku WAV w języku C/C++

ten sposób mogę odczytać pliku w tej chwili:

Readi = fread (& bps, 1, 2, audio); printf ("bity na próbkę =% d \ n", bps);

Z góry dziękuję.

+3

http://www.mega-nerd.com/libsndfile/ http://ccrma.stanford.edu/software/snd/sndlib/ to dwie biblioteki, które mogą pomóc w pracy z WAV – Patashu

Odpowiedz

15

Moja pierwsza rekomendacja to skorzystanie z biblioteki. Większość rozwiązań dźwiękowych wydaje się przesadna, więc prosta biblioteka (taka jak ta zalecana w komentarzu do twojego pytania, libsndfile) powinna wystarczyć.

Jeśli chcesz po prostu wiedzieć, jak czytać pliki WAV, abyś mógł napisać własną (ponieważ twoja szkoła może odwrócić się od korzystania z biblioteki, jak każda inna normalna osoba), szybkie wyszukiwanie google da ci wszystkie potrzebne informacje: plus some people who have already wrote many tutorials on reading the .wav format.

Jeśli nadal go nie dostaniesz, oto mój własny kod, w którym czytam nagłówek i wszystkie inne fragmenty pliku danych WAV/RIFF, aż dojdę do porcji danych. Opiera się na exclusively off the WAV Format Specification. Wyodrębnianie rzeczywistych danych dźwiękowych nie jest bardzo trudne: możesz albo odczytać je jako surowe i użyć go jako surowego, albo przekonwertować do formatu, w którym miałbyś większy komfort wewnętrzny (32-bitowe nieskompresowane dane PCM lub coś takiego).

Po zapoznaniu się z poniższym kodem zastąp reader.Read...(...) odpowiednikami fread dla wartości całkowitych i bajtów wskazanego typu. WavChunks jest enum, że to mała wartości endian identyfikatorów wewnątrz fragmentu pliku WAV, a zmienna format jest jednym z rodzajów typów WAV, które mogą być zawarte w formacie WAV pliku:

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

, dlaczego RIFF jest zapisywany w szesnastkowym odwrocie? Wiem o małym/dużym endianie, ale wszystkie edytory szesnastkowe, których użyłem, pokazują je jako RIFF, zamiast FFIR, czy robią jakąś dziwną konwersję za kulisami, czy coś innego się dzieje? – MarcusJ

+0

Wierzę, że @MarcusJ ma rację powinien przeczytać RIFF, tutaj jest opis formatu falowego http://soundfile.sapp.org/doc/WaveFormat/, więc uważam, że powinien to być RiffHeader = 0x52494646, ponieważ format stwierdza, że ​​jest duży - pole ormiańskie – alexm

Powiązane problemy