[c] wav-bestand manipuleren
Geplaatst: za 12 apr 2008, 10:18
Ik heb volgende opdracht gekregen in C, waar ik weinig tot geen ervaring in heb.
# Project: inlezen en bewerken van een .wav bestand in C
* Opgave: Schrijf een applicatie in C die
o een WAV bestand inleest (test file)
o de volgende informatie over dit bestand kan afdrukken naar de standaard uitvoer:
+ de naam van de applicatie (gebruik hier voor de eigenschappen van argv), informatie over de auteur en hulp over het gebruik
+ alle gegevens die in de header chunk staan. Een wav bestand bestaat uit een header en data chunk. De header chunk bevat metadata over de wav file (bijv. lengte, samplerate, mono of stereo, enz...) en de data chunk bevat de eigenlijke data
+ een waarschuwing indien uw applicatie niet in staat is de data chunk van het wav bestand te interpreteren (bvb doordat uw applicatie de gebruikte encodering niet ondersteunt)
o een nieuw bestand wegschrijft dat de volgende aanpassingen kan bevatten:
+ aangepaste samplerate (dit betekent de meta data uit de header chunk aanpassen): hierdoor zal het resultaat sterk vervormd klinken (waarom?)
+ decimatie: verlagen van de samplerate met een bepaalde factor waarbij je ervoor zorgt dat je voor de nieuwe sample periode slechts 1 sample per periode krijgt (door samples te elimineren) en de nieuwe samples nog steeds op dezelfde tijdstippen afgespeeld worden (neem voor deze factor een macht van 2) (dit betekent zowel de meta data in de header als de data in de data chunk aanpassen)
+ aanpassen van het volume: vermenigvuldig alle samples met een constante waarde (waarschuwing: pas op voor overflow!)
+ echo-effect: tel bij elke sample op tijdstip t de waarde van de sample op tijdstip t-delay op, let erop dat er geen clipping optreedt ! Neem hiervoor uw voorzorgen (zie vorige mogelijkheid)
+ fading: zorg ervoor dat het geluidsfragment gedempt begint (samplewaarde * factor << 1), en de samples na een bepaalde tijd hun originele waarde terugkrijgen
+ conversie mono <-> stereo (Header en Data chunk aanpassen)
+ clipping detectie: rapporteer de samples waarvan de waarde gelijk is aan de maximale waarde die met de gebruikte woordlengte bereikt kan worden; hoe meer opeenvolgende samples deze waarde hebben, hoe erger het clipping effect is. Past dit eventueel toe op wav files van bestaande cd's.
+ maximale versterking zonder clipping: vermenigvuldig alle samples met een constante waarde zodat de sample met de grootste waarde de grootste waarde heeft dat in de gebruikte woordlengte past (Data chunck aanpassen)
Het gaat om het aanpassen van dit programma:
Dit programma werkt, wat betekent dat ik een nieuw bestand out.wav krijg, voorlopig echter identiek aan test.wav. Wie kan mij op weg helpen, door bijvoorbeeld één aanpassing te schrijven (decimatie, volume-verlaging, echo-effect...) zodat ik mij hierop kan baseren voor de overige aanpassingen. Ik vertel er nog bij dat de waarden voor de aanpassingen door de gebruiker moeten kunnen worden ingegeven via het toetsenbord.
Hartelijk dank!
# Project: inlezen en bewerken van een .wav bestand in C
* Opgave: Schrijf een applicatie in C die
o een WAV bestand inleest (test file)
o de volgende informatie over dit bestand kan afdrukken naar de standaard uitvoer:
+ de naam van de applicatie (gebruik hier voor de eigenschappen van argv), informatie over de auteur en hulp over het gebruik
+ alle gegevens die in de header chunk staan. Een wav bestand bestaat uit een header en data chunk. De header chunk bevat metadata over de wav file (bijv. lengte, samplerate, mono of stereo, enz...) en de data chunk bevat de eigenlijke data
+ een waarschuwing indien uw applicatie niet in staat is de data chunk van het wav bestand te interpreteren (bvb doordat uw applicatie de gebruikte encodering niet ondersteunt)
o een nieuw bestand wegschrijft dat de volgende aanpassingen kan bevatten:
+ aangepaste samplerate (dit betekent de meta data uit de header chunk aanpassen): hierdoor zal het resultaat sterk vervormd klinken (waarom?)
+ decimatie: verlagen van de samplerate met een bepaalde factor waarbij je ervoor zorgt dat je voor de nieuwe sample periode slechts 1 sample per periode krijgt (door samples te elimineren) en de nieuwe samples nog steeds op dezelfde tijdstippen afgespeeld worden (neem voor deze factor een macht van 2) (dit betekent zowel de meta data in de header als de data in de data chunk aanpassen)
+ aanpassen van het volume: vermenigvuldig alle samples met een constante waarde (waarschuwing: pas op voor overflow!)
+ echo-effect: tel bij elke sample op tijdstip t de waarde van de sample op tijdstip t-delay op, let erop dat er geen clipping optreedt ! Neem hiervoor uw voorzorgen (zie vorige mogelijkheid)
+ fading: zorg ervoor dat het geluidsfragment gedempt begint (samplewaarde * factor << 1), en de samples na een bepaalde tijd hun originele waarde terugkrijgen
+ conversie mono <-> stereo (Header en Data chunk aanpassen)
+ clipping detectie: rapporteer de samples waarvan de waarde gelijk is aan de maximale waarde die met de gebruikte woordlengte bereikt kan worden; hoe meer opeenvolgende samples deze waarde hebben, hoe erger het clipping effect is. Past dit eventueel toe op wav files van bestaande cd's.
+ maximale versterking zonder clipping: vermenigvuldig alle samples met een constante waarde zodat de sample met de grootste waarde de grootste waarde heeft dat in de gebruikte woordlengte past (Data chunck aanpassen)
Het gaat om het aanpassen van dit programma:
Code: Selecteer alles
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct wav_header{
char riff[4]; /* "RIFF" (4 bytes) */
long TotLen; /* File length - 8 bytes (4 bytes) */
char wavefmt[8]; /* "WAVEfmt " (8 bytes) */
long Len; /* Remaining length (4 bytes) */
short format_tag; /* Tag (1 = PCM) (2 bytes) */
short channels; /* Mono=1 Stereo=2 (2 bytes) */
long SamplesPerSec; /* No samples/sec (4 bytes) */
long AvgBytesPerSec; /* Average bytes/sec (4 bytes) */
short BlockAlign; /* Block align (2 bytes) */
short FormatSpecific; /* 8 or 16 bit (2 bytes) */
char data[4]; /* "data" (4 bytes) */
long datalen; /* Raw data length (4 bytes) */
/* ..data follows. Total header size = 44 bytes */
} wav_header_s;
int main(void)
{
wav_header_s header;
FILE *in_fp, *out_fp;
char in_file[40], out_file[40];
short *audiodat;
int filelength, wavlength, datalength;
strcpy(in_file,"test.wav");
if ((in_fp = fopen(in_file, "rb")) == NULL)
{
printf("'%s' is niet te openen.\n", in_file);
exit(0);
}
fread(&header, 44, 1, in_fp); /* Lees wav header */
filelength = header.TotLen; /* Stop de lengte van het bestand uit de struct */
wavlength = header.datalen; /* Lees de lengte van de data uit de struct */
datalength = wavlength/2; /* Het aantal samples: in dit voorbeeld zijn er 2 kanelen: stereo !! */
printf("Lengte bestand = %d bytes\n", filelength);
printf("Aantal kanalen = %d channels\n", header.channels);
printf("Datalengte = %d bytes\n", wavlength);
printf("Samples per seconde = %ld bytes\n", header.SamplesPerSec);
printf("Aantal samples = %d\n", datalength);
printf("Formaat = %d\n", header.FormatSpecific);
printf("sizeof(short) = %d\n", sizeof(short)); /* Om jullie er even aan te herinneren... */
audiodat = (short *) calloc(datalength, 2); /* Alloceer geheugen voor de samples */
if (audiodat == NULL)
{
printf("Niet genoeg geheugen om de samples in het geheugen te lezen.\n");
exit(0);
}
fread(audiodat, 2, datalength, in_fp);
printf("De eerste 2 samples zijn %d %d\n", audiodat[0], audiodat[1]);
printf("De laatste 2 samples zijn %d %d\n", audiodat[datalength-2], audiodat[datalength-1]);
strcpy(out_file,"out.wav");
if ((out_fp = fopen(out_file, "wb")) == NULL)
{
printf("%s is niet te openen !\n",out_file);
exit(0);
}
fwrite(&header, 44, 1, out_fp); /* Schrijf de header weg in het nieuwe bestand */
fwrite(audiodat, 2, datalength, out_fp); /* Schrijf de audio samples weg in het nieuwe bestand */
fclose (out_fp);
fclose(in_fp);
free(audiodat);
return 0;
}
Hartelijk dank!