Здрасвуйте! Замахался я.... Не могу правильно записать заголовок 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 байта. (вроде всё так и должно быть....)... но если записывать звук, то виндовс медиа не открывает файл... (http://s2.hostingkartinok.com/uploads/thumbs/2012/09/687ca9c3189b28cfe4d6ee59b0a1d136.png) (http://hostingkartinok.com/show-image.php?id=687ca9c3189b28cfe4d6ee59b0a1d136)
И ещё одно важное замечание.... если открыть в блокноте нормальный рабочий wav файл, то там чётко видны слова "WAVE", "RIFF" и тд. (http://s2.hostingkartinok.com/uploads/thumbs/2012/09/f5d3c1f15cf5afde5ad411085a2c3944.png) (http://hostingkartinok.com/show-image.php?id=f5d3c1f15cf5afde5ad411085a2c3944)
а если открыть файл, который создан этим кодом, то там не видно слов.... (http://s2.hostingkartinok.com/uploads/thumbs/2012/09/8a7425faee67a6f6ded46db19dcb3231.png) (http://hostingkartinok.com/show-image.php?id=8a7425faee67a6f6ded46db19dcb3231)
Ребята, помогите разобраться что не так, очень надо в короткие сроки написать программу (( Заранее спасибо Вам!
Вот тебе рабочий код из недавнего прошлого - надеюсь разберешься.
Работает с PCM файлами - читает/пишет. Если нужно что-то, отличное от PCM - рекомендую libsndfile.
xokc, Спасибо огромное! Ещё вопрос один... я просто программист - самоучка... есть пробелы в знаниях.... что обозначает данная конструкция?
int sampleRate() const { return _header.format.sampleRate; }
это получается в .h файле функция объявлена и тут же она расписана?