Russian Qt Forum
Ноябрь 22, 2024, 17:10 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Ребятки Помогите с заголовком wav файла!  (Прочитано 8672 раз)
Pes
Гость
« : Сентябрь 11, 2012, 08:02 »

Здрасвуйте! Замахался я.... Не могу правильно записать заголовок wav файла..... Весь инет перелазил.... Есть кучи примеров на C++, но на Qt так и не нашёл... Вся проблема в различии типов... Вот структура, которая представляет собой заголовок (код был взят прям из примера на C++):

Код:
struct Waveheader
{
    // WAV-формат начинается с RIFF-заголовка:

        // Содержит символы "RIFF" в ASCII кодировке
        // (0x52494646 в big-endian представлении)
        char chunkId[4];

        // 36 + subchunk2Size, или более точно:
        // 4 + (8 + subchunk1Size) + (8 + subchunk2Size)
        // Это оставшийся размер цепочки, начиная с этой позиции.
        // Иначе говоря, это размер файла - 8, то есть,
        // исключены поля chunkId и chunkSize.
        unsigned long chunkSize;

        // Содержит символы "WAVE"
        // (0x57415645 в big-endian представлении)
        char format[4];

        // Формат "WAVE" состоит из двух подцепочек: "fmt " и "data":
        // Подцепочка "fmt " описывает формат звуковых данных:

        // Содержит символы "fmt "
        // (0x666d7420 в big-endian представлении)
        char subchunk1Id[4];

        // 16 для формата PCM.
        // Это оставшийся размер подцепочки, начиная с этой позиции.
        unsigned long subchunk1Size;

        // Аудио формат, полный список можно получить здесь http://audiocoding.ru/wav_formats.txt
        // Для PCM = 1 (то есть, Линейное квантование).
        // Значения, отличающиеся от 1, обозначают некоторый формат сжатия.
        unsigned short audioFormat;

        // Количество каналов. Моно = 1, Стерео = 2 и т.д.
        unsigned short numChannels;

        // Частота дискретизации. 8000 Гц, 44100 Гц и т.д.
        unsigned long sampleRate;

        // sampleRate * numChannels * bitsPerSample/8
        unsigned long byteRate;

        // numChannels * bitsPerSample/8
        // Количество байт для одного сэмпла, включая все каналы.
        unsigned short blockAlign;

        // Так называемая "глубиная" или точность звучания. 8 бит, 16 бит и т.д.
        unsigned short bitsPerSample;

        // Подцепочка "data" содержит аудио-данные и их размер.

        // Содержит символы "data"
        // (0x64617461 в big-endian представлении)
        char subchunk2Id[4];

        // numSamples * numChannels * bitsPerSample/8
        // Количество байт в области данных.
        unsigned long subchunk2Size;

        // Далее следуют непосредственно Wav данные.
};
Потом я заполняю поля заголовка:

Код:
void MainWindow::on_pushButton_clicked()
{
    OutFile->seek(0);
    head.chunkId[0]='R';
    head.chunkId[1]='I';
    head.chunkId[2]='F';
    head.chunkId[3]='F';

    head.chunkSize = OutFile->size() * 8 - 8;

    head.format[0] = 'W';
    head.format[1] = 'A';
    head.format[2] = 'V';
    head.format[3] = 'E';

    head.subchunk1Id[0] = 'f';
    head.subchunk1Id[1] = 'm';
    head.subchunk1Id[2] = 't';
    head.subchunk1Id[3] = ' ';

    head.subchunk1Size = 16;

    head.audioFormat = 1;

    head.numChannels = format.channels();

    head.sampleRate = format.frequency();

    head.byteRate = head.sampleRate * head.numChannels * format.sampleSize() / 8;

    head.blockAlign = head.numChannels * format.sampleSize() / 8;

    head.bitsPerSample = format.sampleSize();

    head.subchunk2Id[0] = 'd';
    head.subchunk2Id[1] = 'a';
    head.subchunk2Id[2] = 't';
    head.subchunk2Id[3] = 'a';

    head.subchunk2Size = OutFile->size() - 44;

    QDataStream str(OutFile);
    writeWaveHeader(head,&str);
    OutFile->close();

}
И записываю в файл этот заголовок (приходится всё преобразовывать к типам Qt, иначе не получается... а также приходится записывать каждое поле отдельно... целую структуру тоже не получается....):

Код:
void MainWindow::writeWaveHeader(WAVHEADER header, QDataStream* Stream)
{
    for(int i = 0; i < sizeof(header.chunkId); i++)
        *Stream << (quint8*)header.chunkId[i];

    *Stream << (quint32)header.chunkSize;

    for(int i = 0; i < sizeof(header.format); i++)
        *Stream << (quint8*)header.format[i];
    for(int i = 0; i < sizeof(header.subchunk1Id); i++)
        *Stream << (quint8*)header.subchunk1Id[i];

    *Stream << (quint32)header.subchunk1Size << (quint16)header.audioFormat
            << (quint16)header.numChannels << (quint32)header.sampleRate
            << (quint32)header.byteRate << (quint16)header.blockAlign
            << (quint16)header.bitsPerSample;
    for(int i = 0; i < sizeof(header.subchunk2Id); i++)
        *Stream << (quint8*)header.subchunk2Id[i];

    *Stream << (quint32)header.subchunk2Size;
}

после такой записи, размер файла 44 байта. (вроде всё так и должно быть....)... но если записывать звук, то виндовс медиа не открывает файл...   

И ещё одно важное замечание.... если открыть в блокноте нормальный рабочий wav файл, то там чётко видны слова "WAVE", "RIFF" и тд.   

а если открыть файл, который создан этим кодом, то там не видно слов....   

Ребята, помогите разобраться что не так, очень надо в короткие сроки написать программу (( Заранее спасибо Вам!
« Последнее редактирование: Сентябрь 11, 2012, 08:06 от Pes » Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #1 : Сентябрь 11, 2012, 08:10 »

Вот тебе рабочий код из недавнего прошлого - надеюсь разберешься.
Работает с PCM файлами - читает/пишет. Если нужно что-то, отличное от PCM - рекомендую libsndfile.
Записан
Pes
Гость
« Ответ #2 : Сентябрь 11, 2012, 08:25 »

xokc, Спасибо огромное! Ещё вопрос один... я просто программист - самоучка... есть пробелы в знаниях.... что обозначает данная конструкция?

Код:
int sampleRate() const { return _header.format.sampleRate; }

это получается в .h файле функция объявлена и тут же она расписана?
Записан
Bepec
Гость
« Ответ #3 : Сентябрь 11, 2012, 09:01 »

Да, это разрешается в стандарте С++ Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.211 секунд. Запросов: 22.