wavread, wavwrite and sound
Nilesh Madhu <[email protected]> Wed, 19 Nov 2003 08:16:45 -0600
| Newsgroups | gmane.comp.gnu.octave.sources |
|---|---|
| Message-ID | <[email protected]> |
Hi, I've read past postings regarding the wavread, wavwrite and the sound functions. I would like to offer my code for these functions. Also, i've modified the sound function so that it can be used like in matlab with variable sampling frequencies. Let me know if there are any queries/ doubts Nilesh -- Nilesh Madhu, M.Sc. (Communications Engineering), Institute for Communications Acoustics, Ruhr University Bochum, D-44780, Bochum. Tel.: +49 234 32 22496 Fax : +49 234 32 14165 Mail: [email protected] Web : http://www.ika.ruhr-uni-bochum.de
sound.m
(text/plain, 1.2 KB)
%SOUND Play a vector as a sound.
% sound (s, Fs, NBits)
% Plays the audio data stored in the vector s, at the sampling
% frequency Fs and the number of bits per sample NBits to the speakers.
%
% Author: NM <Nilesh Madhu>
% Created: 15 September 2003
% Copyright (C) 2003 Nilesh Madhu
%
% This file is part of Octave distribution at the Institute for
% Communications Acoustics (IKA) at the RU Bochum.
%
function sound(s, Fs, NBits)
% Handling the different sampling frequencies in linux is difficult using the
% octave PLAYAUDIO command. As a result, a work around solution is to copy the
% data into a '.wav' file temporarily and then play this wave file by issung a
% SYSTEM call to PLAY. If no sampling frequency is mentioned, the default sampling
% frequency is 8kHz at 16 bits (2 bytes) per sample per channel.
SamplingFrequency = 8000; % Sampling frequency.
BitspSamp = 16; % number of bits per sample.
if nargin == 2
SamplingFrequency = Fs;
if nargin == 3
BitspSamp = NBits;
end
end
wavwrite("temp.wav", s, SamplingFrequency , BitspSamp);
commandstr = ['play -r ', int2str(SamplingFrequency),' temp.wav'];
system(commandstr);
cleanupstr = ('rm -f temp.wav');
system(cleanupstr);
wavread.m
(text/plain, 2.4 KB)
%WAVREAD Simulates the matlab wavread command.
% [S Fs NBits] = wavread(WAVEFILENAME)
%Information about WAVREAD
% Wave files are in the Resource Interchange File Format (RIFF),
% which consists of a variable number of chunks containing either
% header information (for example, the wave format of sound samples) or
% data (the samples themselves). (See www.sonicspot.com/ for more information.)
function [s, Fs, NBits] = wavread(WAVEFILENAME)
LName = length(WAVEFILENAME);
if (LName < 3)
WAVEFILENAME = [WAVEFILENAME,'.wav'];
else
file_ext = WAVEFILENAME(length(WAVEFILENAME)-2:end);
if (file_ext~='wav')
WAVEFILENAME = [WAVEFILENAME,'.wav'];
end
end
fid = fopen(WAVEFILENAME, 'r', 'ieee-le');
if fid < 0
disp('Error! Wave file does not exist or path is mis-spelled');
return;
end
% Start reading in the RIFF data.
ChunkID = char(fread(fid,4,"uchar",0,"ieee-le").');
if (ChunkID~='RIFF')
disp('Error! File is not in a RIFF format');
return;
end
% Get the file size
fseek(fid, 0x04, SEEK_SET); % Rewinding the file.
ChunkSize = fread(fid, 1, "uint", 0, "ieee-le");
% Check the RIFF Type ID. Should be 'WAVE'
RIFFTypeID = char(fread(fid, 4, "uchar", 0, "ieee-le").');
if (RIFFTypeID ~= 'WAVE')
disp('Error! File is not a WAVE file');
return;
end
ChunkID = fread(fid, 4, "uchar", 0, "ieee-le"); % Returns the string 'fmt'
ChunkSiz = fread(fid, 1, "uint", 0, "ieee-le"); % always 16 bytes
Compression = fread(fid, 1, "int16", 0, "ieee-le"); % Compression code
NumberofChannels = fread(fid, 1, "int16", 0, "ieee-le"); % Number of channels
Fs = fread(fid, 1, "int32", 0, "ieee-le"); % Sampling rate
Byps = fread(fid, 1, "int32", 0, "ieee-le"); % Bytes per second
BlockAlign = fread(fid, 1, "int16", 0, "ieee-le"); % Block Align
NBits = fread(fid, 1, "int16", 0, "ieee-le"); % NBits
ChunkData = char(fread(fid, 4, "uchar", 0, "ieee-le").'); % 'data'
NumberofDataBytes = (fread(fid, 1, "uint", 0, "ieee-le"));
NumberofSamples = NumberofDataBytes/(NumberofChannels*(NBits/8)); % number of samples
% Enough data obtained for reading in the data based upon the number of
% significant bits per sample.
switch NBits
case 8
MultFact = 128;
dataPrecision = 'uchar';
case 16
MultFact = 32768;
dataPrecision = 'int16';
case 24
MultFact = 2^23;
dataPrecision = 'int16';
end
s = fread(fid, [NumberofSamples NumberofChannels], dataPrecision, 0, 'ieee-le');
if NBits == 8
s = (s/MultFact) - 1;
else
s = s/MultFact;
end
fclose(fid);
wavwrite.m
(text/plain, 3.2 KB)
%WAVWRITE Write a vector into a wave file.
% wavwrite (FileName, s, Fs, NBits)
% Writes the audio data stored in the vector s, at the sampling
% frequency Fs and the number of bits per sample NBits to the file FileName.
%
% Author: NM <Nilesh Madhu>
% Created: 15 September 2003
% Copyright (C) 2003 Nilesh Madhu
%
% This file is part of Octave distribution at the Institute for
% Communications Acoustics (IKA) at the RU Bochum.
%
function wavwrite(FileName, s, Fs, NBits)
% Handling the different sampling frequencies in linux is difficult using the
% octave PLAYAUDIO command. As a result, a work around solution is to copy the
% data into a '.wav' file temporarily and then play this wave file by issung a
% SYSTEM call to PLAY. If no sampling frequency is mentioned, the default sampling
% frequency is 8kHz at 16 bits (2 bytes) per sample per channel.
SamplingFrequency = 8000; % Sampling frequency.
if nargin > 2
SamplingFrequency = Fs;
if nargin < 4
NBits = 16; % number of significant bits per sample.
end
end
% Setting the parameters for writing data depending upon the
% number of significant bits.
switch NBits
case 8
MultFact = 128;
dataPrecision = 'uchar';
s = (s+1)*MultFact;
case 16
MultFact = 32768;
dataPrecision = 'int16';
s = s*MultFact;
case 24
MultFact = 2^23;
dataPrecision = 'int16';
s = s*MultFact;
end
addExt = 0;
if length(FileName) < 3
addExt = 1;
else
file_ext = FileName(end-2:end);
if file_ext~='wav'
addExt = 1;
end
end
if addExt
FileName = [FileName,'.wav'];
end
[fid msg] = fopen(FileName,"wb", "ieee-le");
if fid < 0
disp(msg);
return;
end
[NumSamples NumChannels] = size(s);
if NumSamples < NumChannels
s = s.';
[NumSamples NumChannels] = size(s);
end
% Writing into the '.wav' file.
chunkDataSize = NumSamples*NumChannels*NBits/8; % Size of the samples in the wav file.
% The RIFF Chunk
RIFFChunkID = toascii("RIFF"); % 'RIFF'
countRIFFCkID = fwrite(fid, RIFFChunkID, 'uchar');
RIFFChunkSize = 36+chunkDataSize;
countRIFFCkSiz = fwrite(fid, RIFFChunkSize, 'uint');
% The WAVE type ID and the FORMAT Chunk.
RIFFTypeID = toascii("WAVE"); % 'WAVE'
countRIFFTypeID = fwrite(fid, RIFFTypeID, 'uchar');
ChunkFmt = toascii("fmt "); % 'fmt '
countRIFFTypeID = fwrite(fid, ChunkFmt, 'uchar');
RIFFTypeSiz = 16; % always 16 bytes
countRIFFTypeSiz = fwrite(fid, RIFFTypeSiz, 'uint');
% Specific data for the file
CompressionFormat = 1; % Uncompressed/ PCM
NumberofChannels = NumChannels;
BlockAlign = (NBits/8)*NumChannels;
AvgBytespSec = SamplingFrequency*BlockAlign;
countCompression = fwrite(fid, CompressionFormat, 'int16');
countNumChannels = fwrite(fid, NumChannels, 'int16');
countFs = fwrite(fid, SamplingFrequency, 'int32');
countAvgByps = fwrite(fid, AvgBytespSec, 'int32');
countBlockAlign = fwrite(fid, BlockAlign, 'int16');
countNBits = fwrite(fid, NBits, 'int16');
% Chunk DATA
chunkData = toascii("data"); % 'data'
countChunkData = fwrite(fid, chunkData);
countchunkDataSize = fwrite(fid, chunkDataSize, 'uint');
countAudioSamples = fwrite(fid, s, dataPrecision, 0, 'ieee-le');
%for i = 1:NumSamples
% for j = NumChannels
% fwrite(fid, s(i,j)*32768, 'int16');
% end
%end
fclose(fid);
%command = ['play -r ',num2str(SamplingFrequency),' temp.wav'];
%system(command);