0

I have the following struct which I call using the Read_Header(FILE * InFile), do structs in C++ save data just like classes. For instance, can I only call the function Read_Header once to set all the variable names in the struct from main.cpp, then get the values of the variable names just by calling them directly.

typedef struct RIFF_CHUNCK_DISCRIPTOR {
    char                RIFF[4];        // RIFF Header      Magic header
    int32_t             ChunkSize;      // RIFF Chunk Size  
    int32_t             WAVE[4];        // WAVE Header      

};
typedef struct CRIF_CHUNCK {

    char    Crif[4];
    int32_t Length;
    int32_t CrifCheckSum;
};
typedef struct FMT_CHUNCK_DISCRIPTOR {
    char                fmt[4];         // FMT header       
    int32_t             Subchunk1Size;  // Size of the fmt chunk     
    int16_t             EncodingTag;
    int16_t             NumOfChan;      // Number of channels 
    int32_t             SamplesPerSec;  // Sampling Frequency in Hz                             
    int32_t             bytesPerSec;    // bytes per second 
    int16_t             blockAlign;     // 2=16-bit mono, 4=16-bit stereo 
    int16_t             bitsPerSample;  // Number of bits per sample      
    int16_t             AudioFormat;    // PCM = 0 , ADPCM = 2
    int16_t             SmplesPerChan;
};
typedef struct FACT_CHUNCK {
    char                fact[4];
    int32_t             FactSize;
    int32_t             dwSampleLength;

};
typedef struct META_DATA {
    char                    meta[4];
    uint32_t                HeadData;// <length of the head data - 8>
    uint8_t                 Version;
    uint8_t                 Model;
    uint32_t                Serial;
    uint32_t                RecordingNumber;
    uint16_t                ChunkNumber;
    uint32_t                TimeStamp;
    uint32_t                MetadataChecksum;

};
typedef struct  DATA_SUB_CHUNCK {
    char                Subchunk2ID[4]; // "data"  string   
    int32_t             Subchunk2Size;  // Sampled data length    

};
typedef struct  CDAT {
    char                cdat[4]; // "data"  string   
    int32_t             CdatCheckSum;  // Sampled data length    

};
typedef struct  FOOTER {
    char                foot[4]; // "data"  string   
    int16_t             PrevChunckNumb;  // Sampled data length    
    int16_t             NextChunckNumb;
    int32_t             FooterChunckSum;


};

WORD CWav::Read_Header(FILE* WAVF) {

    int HeaderArraySize = 46;
    int* HeaderData = new int[HeaderArraySize];


    int A = 1;
    while (1) {

        HeaderIDSize = fread(&RCD, 1, sizeof(RIFF_CHUNCK_DISCRIPTOR), WAVF);

        if (RCD.RIFF[0] == 'R' && RCD.RIFF[1] == 'I' && RCD.RIFF[2] == 'F' && RCD.RIFF[3] == 'F') {

            break;
        }

        else {

            fseek(WAVF, A++, SEEK_CUR);

        }

    }
    int C = 1;
    int Cpcm = 1;
    while (1) {
        FmtSize = fread(&FCD, 1, sizeof(FMT_CHUNCK_DISCRIPTOR), WAVF);

        if (FCD.fmt[0] == 'f' && FCD.fmt[1] == 'm' && FCD.fmt[2] == 't') {
            NumOfChanells = FCD.NumOfChan;
            BitsPerSample = FCD.bitsPerSample;
            SampleRate = FCD.SamplesPerSec;

            if (FCD.EncodingTag == 0x0001) {
                PCM = true;
            }
            break;


        }
        else {

            fseek(WAVF, C++, SEEK_SET);

        }
    }

    int T = 1;
    if (PCM == false) {
        while (1) {
            FactSize = fread(&FactC, 1, sizeof(FACT_CHUNCK), WAVF);

            if (FactC.fact[0] == 'f' && FactC.fact[1] == 'a' && FactC.fact[2] == 'c' && FactC.fact[3] == 't') {


                break;

            }
            else {

                fseek(WAVF, T++, SEEK_SET);

            }

        }
    }
    int F = 1;

    while (1) {
        MetaSize = fread(&MetaD, 1, sizeof(FACT_CHUNCK), WAVF);

        if (MetaD.meta[0] == 'm' && MetaD.meta[1] == 'e' && MetaD.meta[2] == 't' && MetaD.meta[3] == 'a') {

            SerialNum = MetaD.Serial;
            RecordingNum = MetaD.RecordingNumber;
            break;

        }
        else {

            fseek(WAVF, F++, SEEK_SET);

        }

    }

    int H = 1;
    while (1) {

        DataChunckSize = fread(&DSC, 1, sizeof(DATA_SUB_CHUNCK), WAVF);
        if (DSC.Subchunk2ID[0] == 'd' && DSC.Subchunk2ID[1] == 'a' && DSC.Subchunk2ID[2] == 't' && DSC.Subchunk2ID[3] == 'a') {

            break;
        }
        else {

            fseek(WAVF, H++, SEEK_SET);
        }

    }

    Cdata_Postion = 1;
    while (1) {

        CdatSize = fread(&CDA, 1, sizeof(DATA_SUB_CHUNCK), WAVF);
        if (CDA.cdat[0] == 'c' && CDA.cdat[1] == 'd' && CDA.cdat[2] == 'a' && CDA.cdat[3] == 't') {

            break;
        }
        else {

            fseek(WAVF, Cdata_Postion++, SEEK_SET);
        }

    }
    int f = 1;
    while (1) {

        FootSize = fread(&Footer, 1, sizeof(DATA_SUB_CHUNCK), WAVF);
        if (Footer.foot[0] == 'f' && Footer.foot[1] == 'o' && Footer.foot[2] == 'o' && Footer.foot[3] == 't') {

            break;
        }
        else {

            fseek(WAVF, f++, SEEK_SET);
        }

    }
    BUFFER_SIZE = DSC.Subchunk2Size / (FCD.NumOfChan * (FCD.bitsPerSample / 8));
    return BUFFER_SIZE;
}
  • 6
    The only difference between `struct` and `class` in C++ is the default access type. `struct` is public by default and `class` is private by default. – Richard Critten Nov 22 '21 at 14:57
  • The mentions of variable *names* are confusing. What do you mean by that? – harold Nov 22 '21 at 14:59
  • @harold https://www.geeksforgeeks.org/variables-in-c/ –  Nov 22 '21 at 15:00
  • 1
    A `struct` has no prescribed layout in memory, the compiler is free to shuffle it around and pad it any way it sees fit. If you want to read some file headers into those, you may want to look into [packed structs](https://stackoverflow.com/questions/21092415/force-c-structure-to-pack-tightly). –  Nov 22 '21 at 15:01
  • 2
    A bit unrelated but your code looks more like "C" with a class added in. typedef struct is a "C" style syntax, in C++ the typedef shouldn't be there. Also try to avoid new/delete where you don't need them. Use filestreams instead of FILE etc. – Pepijn Kramer Nov 22 '21 at 15:07
  • 1
    @dratenik "_Within a `struct` object, addresses of its elements (and the addresses of the bit field allocation units) increase in order in which the members were defined._" - so, I don't see how a compiler could shuffle it around any way it sees fit. Also: "_A pointer to a `struct` can be cast to a pointer to its first member_" - I think this is true if they are all public anyway. – Ted Lyngmo Nov 22 '21 at 15:12
  • @TedLyngmo Ok, only pad then. Added bits of padding between some elements are enough to make it not usable for parsing file headers. –  Nov 22 '21 at 15:14
  • @TedLyngmo I think they mean that there is an implementation defined amount of padding between each member. Looks like `META_DATA` might be troublesome in that respect – Caleth Nov 22 '21 at 15:16
  • @Caleth Yeah, indeed. `Serial` and `TimeStamp` will likely be aligned out of sync. – Ted Lyngmo Nov 22 '21 at 15:20
  • @Caleth -- padding is implementation-specific, but it isn't implementation-defined; that's a term of art in the standard, and it means that a conforming implementation must document what it does. – Pete Becker Nov 22 '21 at 15:55

0 Answers0