From octave-sources-request at bevo dot che dot wisc dot edu Wed Nov 19 08:23:49 2003 Subject: wavread, wavwrite and sound From: Nilesh Madhu To: octave-sources at bevo dot che dot wisc dot edu Date: Wed, 19 Nov 2003 08:16:45 -0600 This is a multi-part message in MIME format. --------------040801030407080901010207 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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: Nilesh dot Madhu at ruhr-uni-bochum dot de Web : http://www.ika.ruhr-uni-bochum.de --------------040801030407080901010207 Content-Type: text/plain; name="sound.m" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sound.m" %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 % 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); --------------040801030407080901010207 Content-Type: text/plain; name="wavread.m" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="wavread.m" %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); --------------040801030407080901010207 Content-Type: text/plain; name="wavwrite.m" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="wavwrite.m" %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 % 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); --------------040801030407080901010207--