2017-05-04 4 views
2

J'essaie de copier un son WAV en C. le fichier d'origine est un fichier de 2 secondes, mais je veux reproduire les données dans le fichier de destination plusieurs fois, de sorte qu'il joue plus longtemps. Par exemple, si je le copie 3 fois, il devrait jouer pendant 6 secondes ... non?boucle dans le fichier WAV dans c (ou C++)

Mais pour une raison quelconque, même si le fichier de destination est plus grand que le fichier d'origine, il reste lu pendant 2 secondes ... Quelqu'un peut-il vous aider s'il vous plaît?

Voici mon 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; 
} 
+1

Vous ne faites pas dans l'en-tête Changements du fichier de sortie. Regardez [ici] (http://soundfile.sapp.org/doc/WaveFormat/) pour la description du format. Vous devriez probablement vous concentrer sur le champ 'Subchunk2Size'. –

+0

Je n'ai fait aucun changement dans l'en-tête. J'y ai pensé mais même si je change le nombre d'échantillons et que je copie l'audio une fois, il joue toujours. Bien sûr, il y a des champs qui DOIVENT rester inchangés (taux d'échantillonnage, nombre de canaux, etc ...) – PhoenixBlue

+0

Je ne connais pas les détails, mais il semble évident que l'en-tête doit être adapté d'une manière ou d'une autre la nouvelle longueur. –

Répondre

0

Lorsque vous modifiez la taille de vos données, vous devez également mettre à jour l'en-tête de sortie.

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); 

De plus, pour vous assurer que vous lisez la vérification du fichier correct que meta->chunk_size taille du fichier == de man1_nb.wav - 8

+0

Pavel, sur votre code, pourquoi "36"? sur la 6ème ligne – PhoenixBlue

+0

@PhoenixBlue C'est le nombre d'octets passé champ chunk_size. 36 est 'sizeof (en-tête) - sizeof (meta-> chunk_id) - sizeof (meta-> chunk_size)' – Pavel

+0

Merci beaucoup! ça a marché! – PhoenixBlue

2

deux de votre lecture et d'écriture des pièces de code sont erronées.

Les fichiers wav ont RIFF format et sont constitués de blocs tlv. Chaque bloc se compose d'en-tête et de données. Typiquement wav fichier se compose de 3 morceaux: morceau de format avec le code FOURCC, le morceau de format avec PCMWAVEFORMAT struct et le bloc de données avec des données sonores. De plus, étant donné que la taille de chaque segment est limitée à 32 bits de longueur, les fichiers volumineux sont construits en concaténant des fichiers wav ensemble.

Vous devez analyser le fragment de bloc et écrire dans le bloc de destination, en mettant à jour les en-têtes en conséquence.

+0

Merci, en regardant dans ce – PhoenixBlue