Почему для чтения из WAV-файла значение SubChunk2Size равно 3452816845? - PullRequest
0 голосов
/ 16 декабря 2018

Я хотел бы открыть выбранный файл WAV, прочитать его заголовок и затем поместить аудиосэмплы из него в массивы.Мне уже удалось прочитать заголовок, и я думаю, что это выглядит довольно хорошо, но есть один вопрос.После заголовка в WAV-файле размещаются образцы, и я хотел бы знать, какой из параметров заголовка указывает, сколько образцов существует, потому что я пока не совсем понимаю эти параметры.Также я хотел бы знать, хорошо ли это, когда SubChunk2Size равен 3452816845.

EDIT // Поскольку я уже знаю, что полученное значение SubChunk2Size является неправильным, я хочу знать, почему это так и как я могу исправитьэто.

Вот страница, которую я рассмотрел: http://soundfile.sapp.org/doc/WaveFormat/

Вот мой код:

#include "pch.h"
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <stdio.h>
#include <cmath>
#include <iostream>
#include <Windows.h>



using namespace std;


struct WAVfile {
    FILE *fp;
    //The "RIFF" chunk descriptor
    char  ChunkID[4];
    DWORD ChunkSize;
    char  Format[4];
    //The "fmt" sub-chunk
    char  Subchunk1ID[4];
    DWORD Subchunk1Size;
    short AudioFormat;
    short NumChannels;
    DWORD SampleRate;
    DWORD ByteRate;
    short BlockAlign;
    short BitsPerSample;
    //The "data" sub-chunk
    char  Subchunk2ID[4];
    DWORD Subchunk2Size;


    WAVfile(const char* title) {
        this->fp = NULL;
        fp = fopen(title, "r");
        if (!fp) {
            getError("Error: Failed to open file");
        }
        fread(ChunkID, sizeof(char), 4, fp);
        if (!strcmp(ChunkID, "RIFF")) {
            getError("Error: Not RIFF format");
        }
        fread(&ChunkSize, sizeof(DWORD), 1, fp);
        fread(Format, sizeof(char), 4, fp);
        if (!strcmp(Format, "WAVE")) {
            getError("Error: Not WAVE format");
        }
        fread(Subchunk1ID, sizeof(char), 4, fp);
        if (!strcmp(Subchunk1ID, "fmt ")) {
            getError("Error: Not fmt");
        }
        fread(&Subchunk1Size, sizeof(DWORD), 1, fp);
        fread(&AudioFormat, sizeof(short), 1, fp);
        fread(&NumChannels, sizeof(short), 1, fp);
        fread(&SampleRate, sizeof(DWORD), 1, fp);
        fread(&ByteRate, sizeof(DWORD), 1, fp);
        fread(&BlockAlign, sizeof(short), 1, fp);
        fread(&BitsPerSample, sizeof(short), 1, fp);
        fread(Subchunk2ID, sizeof(char), 4, fp);
        if (!strcmp(Subchunk2ID, "data")) {
            getError("Error: Missing Data");
        }
        fread(&Subchunk2Size, sizeof(DWORD), 1, fp);

        cout << "The \"RIFF\" chunk descriptor" << endl;
        cout << "ChunkID:\t\t" << ChunkID << endl;
        cout << "ChunkSize:\t\t" << ChunkSize << endl;
        cout << "Format:\t\t\t" << Format << endl;
        cout << endl;
        cout << "The \"fmt\" sub-chunk" << endl;
        cout << "Subchunk1ID:\t\t" << Subchunk1ID << endl;
        cout << "Subchunk1Size:\t\t" << Subchunk1Size << endl;
        cout << "AudioFormat:\t\t" << AudioFormat << endl;
        cout << "NumChannels:\t\t" << NumChannels << endl;
        cout << "SampleRate:\t\t" << SampleRate << endl;
        cout << "ByteRate:\t\t" << ByteRate << endl;
        cout << "BlockAlign:\t\t" << BlockAlign << endl;
        cout << "BitsPerSample:\t\t" << BitsPerSample << endl;
        cout << endl;
        cout << "The \"data\" sub-chunk" << endl;
        cout << "Subchunk2ID:\t\t" << Subchunk2ID << endl;
        cout << "Subchunk2Size:\t\t" << Subchunk2Size << endl;

        char n;
        cin >> n;
    }

    void getError(const char* message) {
        cout << message << endl;
        char n;
        cin >> n;
    }

};



int main()
{
    //MOJE
    //const int N = 8;// 2 * 16;    // 65536 sampli na sekundę
    //complex *x,   *Xfft;
    //complex *d_x, *d_Xfft;
    //int size = N * sizeof(complex);
    WAVfile *wavfile = new WAVfile("Test2.wav");


    return 0;
}

1 Ответ

0 голосов
/ 18 декабря 2018

По всей вероятности, ваш файл существует, но очень короткий.
strcmp () не работает так, как вы думаете - он возвращает 0 ("FALSE"), когда строки равно и ненулевое значение, если они не.Поскольку вы также не контролируете, что fread() возвращает вам (количество байтов), и использование strcmp() также неправильно по причине, указанной в комментариях, файл может содержать все, что вы не заметите.Для справки, вот вывод вашей программы для моего тестового файла WAV:

The "RIFF" chunk descriptor
ChunkID:                RIFF$фW
ChunkSize:              5760036
Format:                 WAVEfmt ►

The "fmt" sub-chunk
Subchunk1ID:            fmt ►
Subchunk1Size:          16
AudioFormat:            1
NumChannels:            2
SampleRate:             8000
ByteRate:               32000
BlockAlign:             4
BitsPerSample:          16

The "data" sub-chunk
Subchunk2ID:            data
Subchunk2Size:          5760000

Обратите внимание на нечетные символы и особенно Format: WAVEfmt ► строка.std::cout ожидает строки с нулевым символом в конце со специальным символом \0 в конце и считывает символы из памяти до тех пор, пока не найдет их, или ОС не убьет ваш процесс для чтения недопустимой памяти.Один из способов исправить эту часть - объявить ChunkID и, например, char ChunkID[5];, а затем инициализировать ChunkID[4] = '\0'.Другой подход заключается в прекращении обработки этих байтовых массивов как строк и выводе их в виде случайных байтов:
std::cout << ChunkID[0] << ChunkID[1] << ChunkID[2] << ChunkID[3]; или
std::cout << std::string(ChunkID, 4);

...