2014-02-06 1 views
0

У меня есть двоичный двоичный файл необработанных аудиопотоков. Я хочу создать wav-файл со свойствами PCM, подписанный 16-битным монофоническим шрифтом с частотой 22050 Гц.Как создать 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 битам.

  2. write<short>(stream, 16 * sizeof(SampleType)); должно быть write<short>(stream, 8 * sizeof(SampleType)); при записи битов на образец.

  3. 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); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^