1

I'm writing a program to manipulate wave audio files. I'd like to have a data structure to represent the file header and I implemented it the following way:

struct WaveFile {
    riff:               [u8; 4], //Marks the file as riff file, value should be: "RIFF"
    file_size:          u32,     //Size of the overall file
    wave:               [u8; 4], //File Type Header. Always should equal "WAVE"
    format:             [u8; 4], //Format chunk marker, sample value: "fmt" with null termination character
    format_len:         u32,     //Length of format data (should be 16 bytes as above)
    format_type:        [u8; 2], //1 - PCM, 3 - IEEE float, 6 - 8bit A law, 7 - 8bit mu law
    num_of_channels:    [u8; 2], // Number of Channels
    sample_rate:        [u8; 4], //Sample Rate in Hz
    byte_rate:          [u8; 4], // bytes per second of recording (Sample Rate * BitsPerSample * Channels) / 8
    audio_type:         [u8; 2],  //1 - 8bit mono, 2 - 8bit stereo / 16bit mono, 4 - 16bit stereo
    bits_per_sample:    [u8; 2], //Bits per sample
    data:               [u8; 4], // Sample value: “data” - data chunk header. Marks the beginning of the data section.
    size_of_data:       [u8; 4], //Size of data section
}

I've also got a vector with data read from the file. These are snippets of code to show you the data structures I use:

struct MyFile {
    content: fs::File,
    metadata: fs::Metadata,
}

let mut audio_file = MyFile {
    content: fs::File::open("gitarka_C3.wav").expect("Couldn't open a file."),
    metadata: fs::metadata("gitarka_C3.wav").expect("Couldn't get file metadata"),
};

let mut file_data = Vec::new();

audio_file
    .content
    .read_to_end(&mut file_data)
    .expect("Couldn't copy file contents to vector");

Now that I have my vector of data and a structure describing the wave file header, I'd like to read data from the vector and write it to the structure.

  1. Can I copy the first 44 bytes of the vector to the 44 byte chunk of memory allocated for my WaveFile structure? I'd like to avoid copying the data from vector to structure field by field.
  2. Is there a better way to create a human readable data structure describing the header? I know in C I could create macros defining specific offsets and sizes and use a simple array (which would solve the copying problem).
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Glamdring
  • 84
  • 1
  • 5
  • 3
    If you want to do anything that depends on the memory layout of the struct `WaveFile`, you need to add the `#[repr(C)]` attribute. The Rust default representation does not make any guarantees about memory layout. – Sven Marnach Dec 11 '19 at 15:52
  • 2
    But you are probably better of implementing a parser for the wave file format in `nom`. – Sven Marnach Dec 11 '19 at 15:53
  • 1
    One solution from the duplicates [applied to your specific case](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=eae7f4efd3d006a9b32799eda49a288e). – Shepmaster Dec 11 '19 at 16:26

0 Answers0