Записать структуру в файл, но неверное значение при повторном чтении с C ++ - PullRequest
0 голосов
/ 27 августа 2018

Я пишу некоторый код для чтения .wav-файла и выполняю некоторый алгоритм, затем записываю в новый файл .wav. Я использую структуру для обозначения заголовка wav, перед записью структуры в файл, все значения в нем - всеправильно, но когда я читаю обратно, некоторые значения в нем изменились, я не знаю почему, вот моя структура:

struct WavHeader{
    public:
            char RIFF[4]={'R','I','F','F'};
            int32_t size0;
            char  WAVE[4]={'W','A','V','E'};
            char FMT[4]={'f','m','t',' '};
            int32_t size1;
            int16_t fmttag;
            int16_t channel;
            int32_t samplespersec;
            int32_t bytepersec;
            int16_t blockalign;
            int32_t bitsEvrSample;
            char DATA[4]={'d','a','t','a'};
            int32_t size2;

            WavHeader(){
                    size0=0;
                    size1=0;
                    fmttag=0;
                    channel=1;
                    samplespersec=0;
                    bytepersec=0;
                    blockalign=0;
                    bitsEvrSample=0;
                    size2=0;
            }
};

вот моя функция для записи в wav (pz игнорирует WavData):

void MTools::write2Wav(const char* fname,WavData* data,WavHeader* wavhead){
    FILE* fid=fopen(fname,"ab+");
    fwrite(wavhead,1,sizeof(WavHeader),fid);
    fclose(fid);
}

Последняя функция - прочитать заголовок wav:

void MTools::loadWavFile(const char* fname,WavData* ret,WavHeader* head){
    FILE* fp=fopen(fname,"rb");
    size_t result;
    if(fp){
            char id[5];
        format_length,sample_rate,avg_bytes_sec,data_size,bits_per_sample;

            result=fread(id,sizeof(char),4,fp);
            id[4]='\0';

            if(!strcmp(id,"RIFF")){

                    result=fread(&(head->size0),sizeof(int16_t),2,fp);
                    result=fread(id,sizeof(char),4,fp);
                    id[4]='\0';

                    if(!strcmp(id,"WAVE")){
                            result=fread(id,sizeof(char),4,fp);

                            result=fread(&(head->size1),sizeof(int16_t),2,fp);


                            result=fread(&(head->fmttag),sizeof(int16_t),1,fp);

                            result=fread(&(head->channel),sizeof(int16_t),1,fp);

                            result=fread(&(head->samplespersec),sizeof(int16_t),2,fp);

                            result=fread(&(head->bytepersec),sizeof(int16_t),2,fp);

                            result=fread(&(head->blockalign),sizeof(int16_t),1,fp);

                            result=fread(&(head->bitsEvrSample),sizeof(int16_t),2,fp);
                            result=fread(id,sizeof(char),4,fp);

                            result=fread(&(head->size2),sizeof(int16_t),2,fp);


                            ret->size=head->size2/sizeof(int16_t);


                            ret->data=(int16_t*)malloc(head->size2);
                            result=fread(ret->data,sizeof(int16_t),ret->size,fp);
                     }      
                    else{
                            cout<<"Error: RIFF File but not a wave file\n";
                    }       
            }       
    else{   
            cout<<"ERROR: not a RIFF file\n";
    }       
    }
    fclose(fp);

}

перед записью (с помощью gdb): enter image description here

после записи и прочтения: enter image description here

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Вам необходимо переписать ваш write2wav так же явно, как и свой loadWavFile, потому что вы никогда не знаете, как данные упакованы (проблемы с выравниванием памяти) в структуре, как вы ожидаете (зависит от компиляторов от параметров компилятора).

0 голосов
/ 27 августа 2018

Вы определяете заголовок как смесь типов, таких как int16 и int32.Но вы только когда-либо читали int16 значения.Например, посмотрите на samplespersec.Я думаю, что если вы настроите типы, это может быть исправлением.

...