2014-02-06 71 views
0

我有一個原始音頻流的二進制二進制文件。我想創建一個帶有屬性PCM簽名的16位單聲道小尾數的採樣率爲22050hz的wav文件。如何創建有PCM簽名的16位wav文件

目前正在使用下面的代碼:

template <typename T> 
void write(std::ofstream& stream, const T& t) { 
    stream.write((const char*)&t, sizeof(T)); 
} 

template <typename SampleType> 
void writeWAVData(const char* outFile, SampleType* buf, size_t bufSize, 
        int sampleRate, short channels) 
{ 
    std::ofstream stream(outFile, std::ios::binary); 
    stream.write("RIFF", 4); 
    write<int>(stream, 36 + bufSize); 
    stream.write("WAVE", 4); 
    stream.write("fmt ", 4); 
    write<int>(stream, 16); 
    write<short>(stream, 1);          // Format (1 = PCM) 
    write<short>(stream, channels);         // Channels //mono/sterio 
    write<int>(stream, sampleRate); 

    write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate 
    write<short>(stream, channels * sizeof(SampleType));   // Frame size 
    write<short>(stream, 16 * sizeof(SampleType));     // Bits per sample 
    stream.write("data", 4); 
    stream.write((const char*)&bufSize, 4); 
    stream.write((const char*)buf, bufSize); 
} 


int wmain(int argc,wchar_t **argv) 
{ 
    std::ifstream is("c:\\stream", std::ios_base::binary); 
    if (is) { 
     // get length of file: 
     is.seekg (0, is.end); 
     int length = is.tellg(); 
     is.seekg (0, is.beg); 
     char * buffer = new char [length]; 
     is.read (buffer,length); 
     writeWAVData("c:\\audio.wav", buffer, length, 22050, 1); 
    } 
} 

誰能幫助我這裏有什麼問題?

+5

究竟錯在何處?編譯錯誤?運行時錯誤?意外的輸出? –

回答

1

通過傳遞char*指針作爲buf參數,樣本類型推導爲char。如果樣本實際上是16位,那麼取決於sizeof(SampleType)的值將是錯誤的。

你可以投到short*;但刪除模板並將樣本大小作爲另一個運行時參數傳遞可能會更好。無論哪種情況,您都應該乘以8(或CHAR_BIT),而不是16,以獲取位數。

1

一對夫婦的問題,我看到的是:

  1. buffer必須short*int16_t*纔能有SampleType是16位。當寫入每個樣本的位時,應該是write<short>(stream, 8 * sizeof(SampleType));

  2. stream.write((const char*)&bufSize, 4);沒有做正確的事情,如果size_t不是4個字節(通常8個字節的64位系統),因爲你基本上是斬去第一個4個字節bufSize和寫他們。您需要到static_cast到32位整數第一:

    uint32_t sz = bufSize; 
    stream.write((const char*)&sz, 4); 
    

可能還有其他的問題,但這些都是刺目的人給我。

0

感謝球員,你是對的。這裏是我最後的工作代碼

template <typename T> 
void write(std::ofstream& stream, const T& t) { 
    stream.write((const char*)&t, sizeof(T)); 
} 

template <typename SampleType> 
void writeWAVData(const char* outFile, SampleType* buf, size_t bufSize, 
        int sampleRate, short channels) 
{ 
    std::ofstream stream(outFile, std::ios::binary); 
    stream.write("RIFF", 4); 
    write<int>(stream, 36 + bufSize); 
    stream.write("WAVE", 4); 
    stream.write("fmt ", 4); 
    write<int>(stream, 16); 
    write<short>(stream, 1);          // Format (1 = PCM) 
    write<short>(stream, channels);         // Channels //mono/sterio 
    write<int>(stream, sampleRate); 

    write<int>(stream, sampleRate * channels * sizeof(SampleType)); // Byterate 
    write<short>(stream, channels * sizeof(SampleType));   // Frame size 
    write<short>(stream, 8 * sizeof(SampleType));     // Bits per sample 
    stream.write("data", 4); 
    uint32_t sz = bufSize; 
    stream.write((const char*)&sz, 4); 
    stream.write((const char*)buf, bufSize); 
} 


int wmain(int argc,wchar_t **argv) 
{ 
    FILE *fhandle=fopen("c:\\stream","rb"); 
    seek(fhandle, 0, SEEK_END); // seek to end of file 
    int length ; = ftell(fhandle); // get current file pointer 
    fseek(fhandle, 0, SEEK_SET); // seek back to beginning of file 
    length = length * 16; 
    short* Data=new short [length]; // Create an element for every sample 
fread(Data,16/8,length/(16/8),fhandle);//read data 
    writeWAVData("c:\\audio.wav", buffer, length, 22050, 1); 
    } 
}