2013-04-18 29 views
10

Tôi hiện đang thực hiện một dự án trường học rất quan trọng. Tôi cần trích xuất thông tin của một tệp WAVE trong C/C++ và sử dụng thông tin để lấy LPC của tín hiệu thoại. Nhưng, để làm được điều đó, tôi cần phải thực hiện một số xử lý trước cho tín hiệu, như thực hiện phân tích Zero và phân tích năng lượng, trong số những thứ khác. Điều đó có nghĩa là tôi cần dấu hiệu và giá trị thực. Vấn đề là tôi không biết cách lấy thông tin hữu ích và định dạng đúng cho điều đó. Tôi đã đọc từng lĩnh vực trong tập tin, nhưng tôi không chắc tôi đang làm đúng. Đề nghị, xin vui lòng?Đọc và xử lý dữ liệu tệp WAV trong C/C++

Đây là cách tôi đọc các tập tin tại thời điểm này:

readI = fread (& bps, 1, 2, âm thanh); printf ("bit trên mỗi mẫu =% d \ n", bps);

Xin cảm ơn trước.

+3

http://www.mega-nerd.com/libsndfile/ http://ccrma.stanford.edu/software/snd/sndlib/ là hai thư viện có thể giúp bạn làm việc với WAVs – Patashu

Trả lời

15

Đề xuất đầu tiên của tôi là sử dụng một số loại thư viện để giúp bạn. Hầu hết các giải pháp âm thanh có vẻ quá mức cần thiết, do đó, một thư viện đơn giản (như được đề nghị trong nhận xét về câu hỏi của bạn, libsndfile) nên thực hiện thủ thuật.

Nếu bạn chỉ muốn biết cách đọc tệp WAV để bạn có thể tự viết (vì trường học của bạn có thể chuyển sang sử dụng thư viện như bất kỳ người nào khác), tìm kiếm nhanh trên google sẽ cung cấp cho bạn tất cả thông tin bạn cần plus some people who have already wrote many tutorials on reading the .wav format.

Nếu bạn vẫn không nhận được nó, đây là một số mã của riêng tôi, nơi tôi đọc tiêu đề và tất cả các phần khác của tệp dữ liệu WAV/RIFF cho đến khi tôi đến đoạn dữ liệu. Nó dựa trên exclusively off the WAV Format Specification. Việc trích xuất dữ liệu âm thanh thực tế không quá khó: bạn có thể đọc dữ liệu thô và sử dụng dữ liệu thô hoặc thực hiện chuyển đổi sang định dạng mà bạn có thêm sự thoải mái với nội bộ (dữ liệu không nén PCM 32 bit hoặc thứ gì đó).

Khi xem mã bên dưới, thay thế reader.Read...(...) bằng các giá trị số nguyên và kích thước byte tương đương của loại được chỉ định tương đương fread. WavChunks là một enum đó là các giá trị Endian nhỏ của các ID bên trong của một tập tin WAV đoạn, và biến format là một trong những loại các loại định dạng WAV có thể được chứa trong hộp thoại Format WAV file:

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

tại sao RIFF được viết bằng hex ngược? Tôi biết về ít/lớn endian, nhưng tất cả các biên tập viên hex tôi đã sử dụng cho thấy nó như RIFF, thay vì FFIR, họ đang làm một số chuyển đổi kỳ lạ đằng sau hậu trường, hoặc là cái gì khác đang xảy ra? – MarcusJ

+0

Tôi tin rằng @MarcusJ là đúng nên đọc RIFF, đây là một mô tả của định dạng sóng http://soundfile.sapp.org/doc/WaveFormat/ vì vậy tôi tin rằng nó nên được RiffHeader = 0x52494646 như định dạng nói nó là một lớn -trường cánh – alexm

Các vấn đề liên quan