0
$\begingroup$

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);
fclose(fidr);
fclose(fidw);

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

% plot
figure(1)
set(1, 'color', 'w')
subplot(311),plot(x)
grid on, box on, axis tight, title('.wav (f_s = 44100 Hz)')
subplot(312),plot(x_22)
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

$\endgroup$
3
  • $\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$ Commented Feb 12, 2019 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$ Commented Feb 12, 2019 at 14:13
  • $\begingroup$ @MarcusMüller could you indicate me a forum inside StackExcahnge for this subject questions? $\endgroup$ Commented Feb 12, 2019 at 14:20

1 Answer 1

1
$\begingroup$

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.

$\endgroup$
2
  • $\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$ Commented Feb 12, 2019 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$ Commented Feb 12, 2019 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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