I want to convert a .wav file with a sampling frequency of 44100 Hz to a 16 depth .pcm.

I don't why I'm getting those peaks at the beginning of .pcm plot (second figure below 2). If you could explain and tell me how I can correct it, I would very much appreciate it.

This is my attempt:

% determine the least common multiple (lcm) of fsin and fsout
fsin  = fs;
fsout = 22050;
m     = lcm(fsin, fsout);
% determine the up and down sampling rates
up   = m/fsin;
down = m/fsout;
% resample the input using the computed up/down rates
x_22 = resample(x, up, down);
audiowrite([a_filename(1:11),'_22050','.wav'], x_22, fsout);
precision = 'int16';
fidr      = fopen([a_filename(1:11), '_22050','.wav'], 'r');  % open .wav file to read 
fidw      = fopen([a_filename(1:11), '_22050','.pcm'], 'wb'); % open .pcm file to write
w         = int16(fread(fidr, inf, precision));% read wav file
fwrite(fidw, w, precision);

fidr2     = fopen([a_filename(1:11),'_22050','.pcm'], 'r');
[data, ~] = fread(fidr2, 'short');

% plot
set(1, 'color', 'w')
grid on, box on, axis tight, title('.wav (f_s = 44100 Hz)')
grid on, box on, axis tight, title('.wav (f_s = 22050 Hz)') 
subplot(313), plot(data)
grid on, box on,  axis tight, title('.pcm (16 bit depth)')

These are the resuts: Here are all the steps of the conversion: . wav 44100 Hz > .wav 22050 Hz > 16 bit .pcm

This is the zoom in on the thrid subplot to see the peaks:

Unknown peaks

  • $\begingroup$ probably because you have a bug? Check whether these file formats actually work like this. anyway, this doesn't seem to be a signal processing, but more of a general programming question related to how to deal with a specific file format. $\endgroup$ – Marcus Müller Feb 12 '19 at 12:56
  • $\begingroup$ @MarcusMüller thank you. Apparently no bug. I just had to remove the first 44 bytes from the .wav file when doing the reading. $\endgroup$ – Pereira da Silva Feb 12 '19 at 14:13
  • $\begingroup$ @MarcusMüller could you indicate me a forum inside StackExcahnge for this subject questions? $\endgroup$ – Pereira da Silva Feb 12 '19 at 14:20

That sure looks like your are including the .WAV file header as part of your data.

When you read your file in, and write it out, using the file operations, you are not accounting for the header. The header can vary in size (it's actually three RIFF headers), but is usually 44 bytes long.

These are the headers in my own (C++) words:

struct FirstHeader
char     RiffID[4];
int      RiffLength;
char     WaveID[4];
char     FormatID[4];
int      FormatLength;

struct SecondHeader
short    Always0x01;
short    TrackCount;
int      SamplesPerSecond;
int      BytesPerSecond;
short    BytesPerSample;
short    BitsPerReading;
char     Filler[16];

struct ThirdHeader
char     DataID[4];
int      DataLength;

Do a search on "Wav file header" and you can get lots of details. If you don't need any of the parameters, I suppose just looking for the "data" in the header and the next 4 bytes are the UINT32 value of the length. So your data starts the byte after.

Otherwise, follow the RiffLength and FormatLength to get to the DataID field.

The file can be mono or stereo, 8 16 or 24 bit, etc.

| improve this answer | |
  • $\begingroup$ I've done it. I used fseek to skip the header. >> fseek(fidr, 44, -1);% Skip past header, which is 44 bytes long. Thank you! $\endgroup$ – Pereira da Silva Feb 12 '19 at 14:14
  • $\begingroup$ @PereiradaSilva, You're welcome. Be careful though, not all headers are 44 bytes long. To do it properly, you need to read the length bytes in the header. $\endgroup$ – Cedron Dawg Feb 12 '19 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.