简体   繁体   中英

loop through WAV file in c(or c++)

I am trying to copy a WAV sound in C. the original file is a 2 seconds file, but I want to replicate the data in the destination file several times, so that it plays longer. For example, if I copy it 3 times, it should play for 6 seconds... right?

But for some reason, even though the destination file is bigger than the original file, it still plays for 2 seconds... Can anyone help please?

Here is my code:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

typedef struct header_file
{
    char chunk_id[4];
    int chunk_size;
    char format[4];
    char subchunk1_id[4];
    int subchunk1_size;
    short int audio_format;
    short int num_channels;
    int sample_rate;
    int byte_rate;
    short int block_align;
    short int bits_per_sample;
    char subchunk2_id[4];
    int subchunk2_size; 
} header;

typedef struct header_file* header_p;




int main()

{
    FILE * infile = fopen("../files/man1_nb.wav","rb");     // Open wave file in read mode
    FILE * outfile = fopen("../files/Output.wav","wb");     // Create output ( wave format) file in write mode

    int BUFSIZE   = 2;                  // BUFSIZE can be changed according to the frame size required (eg: 512)
    int count     = 0;                      // For counting number of frames in wave file.
    short int buff16[BUFSIZE];              // short int used for 16 bit as input data format is 16 bit PCM audio
    header_p meta = (header_p)malloc(sizeof(header));   // header_p points to a header struct that contains the wave file metadata fields
    int nb;                         // variable storing number of byes returned
    if (infile)
    {
        fread(meta, 1, sizeof(header), infile); // Read only the header
        fwrite(meta,1, sizeof(*meta), outfile); // copy header to destination file
        int looper = 0;                         // number of times sound data is copied
        for(looper=0; looper <2; looper++){

        while (!feof(infile))
        {
            nb = fread(buff16,1,BUFSIZE,infile);        // Reading data in chunks of BUFSIZE
            count++;                                    // Incrementing Number of frames
            fwrite(buff16,1,nb,outfile);                // Writing read data into output file
        }
        fseek(infile, 44, SEEK_SET);                    // Go back to end of header
        }
    }
fclose(infile); fclose(outfile);
return 0;
}

Both of your read and write code parts are wrong.

wav files have RIFF format and consists of tlv chunks. Each chunk consists of header and data. Typically wav file consists of 3 chunks: format chunk with FOURCC code, format chunk with PCMWAVEFORMAT struct and data chunk with sound data. Also since size of each chunk is limited by 32 bit of length holding field, large files are constructed by concatenating wav files together.

You need to parse file chunk-by-chunk, and write into destination chunk-by-chunk, updating headers accordingly.

When you change size of your data you'll need to update output header as well.

long total_bytes_written_to_outfile = ftell(outfile);

// correct chunk_size and subchunk2_size just before closing outfile:
fseek(outfile, 0, SEEK_SET);
int size = total_bytes_written_to_outfile - sizeof(*meta);
meta->chunk_size = sizeof(header) - sizeof(meta->chunk_id) - sizeof(meta->chunk_size) + size;
meta->subchunk2_size = size;
fwrite(meta, 1, sizeof(*meta), outfile);
fclose(outfile);

Also, to make sure you are reading correct file check that meta->chunk_size == file size of man1_nb.wav - 8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM