Matlab file doesn't produce audio

3 views (last 30 days)
Jacob
Jacob on 7 Mar 2024
Commented: Walter Roberson on 7 Mar 2024
Hi, I am trying to produce an audio file out of the following matlab code. When I go to play these Matlab Files Matlab just hangs and I am unable to get any output out of them. Is there a specific way that these files have to be played to get a successful output? Any help is appreciated Matlab code below
I am trying to play the bach_fugue.mat file with the 2 matlab files below.
First File
clear;
load bach_fugue.mat;
fs = 11025; % set sampling frequency
bpm = 120; % set tempo in beats per minute
bps = bpm/60; % tempo in beats per second
spb = 1/bps; % seconds per beat (inverse of bps)
spp = spb/4; % seconds per pulse
sampp = fs*spp; % samples per pulse
voices = length(theVoices);
xx = zeros(1,560000);
for i = 1:voices % for loop that runs through different voices in theVoices
notenum = length(theVoices(i).noteNumbers);
n1 = 1;
% establish value for rest
rest = key2note(0,theVoices(i).startPulses(1)*spp,i);
n2 = n1 + length(rest) - 1;
xx(n1:n2) = xx(n1:n2) + rest;
n1 = n2 + 1;
% for loop that runs through each note in current voice
for k = 1:notenum
dur = theVoices(i).durations(k)*spp;
keynum = theVoices(i).noteNumbers(k);
firstPulse = theVoices(i).startPulses(k);
tone = key2note(keynum, dur, i);
n2 = n1 + length(tone) - 1;
xx(n1:n2) = xx(n1:n2) + tone;
n1 = n2 + 1;
% conditional statement to create inter-note pauses
if k < notenum
if (theVoices(i).startPulses(k+1)-firstPulse) > dur
pause = key2note(0,theVoices(i).startPulses(k+1)-(firstPulse)*spp,i);
n2 = n1 + length(pause) - 1;
xx(n1:n2) = xx(n1:n2) + pause;
n1 = n2 + 1;
end
end
end
end
Index exceeds the number of array elements. Index must not exceed 560000.
soundsc(xx, fs);
specgram(xx,512,fs);
Second File
function xx = key2note(keynum, dur, voicenum)
fs = 11025;
tt = 0:(1/fs):dur;
if (keynum == 0)
xx = zeros(1, length(tt)); % pause if no note
else
freq = 440*2^((keynum-49)/12);
if (voicenum == 1)
f = freq*[1 2 3 4]';
A = [1 1/2 1/4 1/8];
elseif (voicenum == 2)
f = freq*[1 3 5]';
A = 0.8*[1 1/2 1/4];
elseif (voicenum == 3)
f = 1.5*freq*[1 2 3 4]';
A = [1 1/2 1/4 1/8];
end
xx = A*cos(2*pi*f*tt);
% ADSR Envelope
if( dur>0.15 )
E = interp1([0,0.05,0.1,dur-0.05,dur],[0,1,0.9,0.8,0],tt);
elseif( dur>0.10 )
E = interp1([0,0.05,dur-0.05,dur],[0,1,0.8,0],tt);
else
E = interp1([0,0.05,dur],[0,1,0],tt);
end
% multiply xx by ADSR envelope
xx = xx.*E;
end
end
  10 Comments
Jacob
Jacob on 7 Mar 2024
So is there a way to fix that or is it an error in the file thus not fixable??
Walter Roberson
Walter Roberson on 7 Mar 2024
You can set a buffer size and quit filling it when you get to the end of the buffer.
load bach_fugue.mat;
fs = 11025; % set sampling frequency
bpm = 120; % set tempo in beats per minute
bps = bpm/60; % tempo in beats per second
spb = 1/bps; % seconds per beat (inverse of bps)
spp = spb/4; % seconds per pulse
sampp = fs*spp; % samples per pulse
voices = length(theVoices);
maxXX = 560000;
xx = zeros(1,maxXX);
for i = 1:voices % for loop that runs through different voices in theVoices
notenum = length(theVoices(i).noteNumbers);
n1 = 1;
% establish value for rest
rest = key2note(0,theVoices(i).startPulses(1)*spp,i);
n2 = n1 + length(rest) - 1;
xx(n1:n2) = xx(n1:n2) + rest;
n1 = n2 + 1;
% for loop that runs through each note in current voice
for k = 1:notenum
dur = theVoices(i).durations(k)*spp;
keynum = theVoices(i).noteNumbers(k);
firstPulse = theVoices(i).startPulses(k);
tone = key2note(keynum, dur, i);
n2 = n1 + length(tone) - 1;
if n2 > maxXX
margin = maxXX - n1 + 1;
tone = tone(1:margin);
n2 = maxXX;
end
disp(-[n1, n2])
xx(n1:n2) = xx(n1:n2) + tone;
n1 = n2 + 1;
if n1 > maxXX; break; end
% conditional statement to create inter-note pauses
if k < notenum
if (theVoices(i).startPulses(k+1)-firstPulse) > dur
pause = key2note(0,theVoices(i).startPulses(k+1)-(firstPulse)*spp,i);
n2 = n1 + length(pause) - 1;
if n2 > maxXX
margin = maxXX - n1 + 1;
pause = pause(1:margin);
n2 = maxXX;
end
disp([n1, n2])
xx(n1:n2) = xx(n1:n2) + pause;
n1 = n2 + 1;
if n1 > maxXX; break; end
end
end
end
end
-4136 -5514
5515 45480
-45481 -46859
46860 96472
-96473 -98126
98127 168411
-168412 -170065
170066 259644
-259645 -261298
261299 370170
-370171 -371549
371550 488690
-488691 -490069
490070 560000
-48236 -49614
49615 398280
-398281 -399659
399660 560000
-136436 -137814
137815 560000
soundsc(xx, fs);
Timeout occurred while trying to communicate to the device.
specgram(xx,512,fs);
function xx = key2note(keynum, dur, voicenum)
fs = 11025;
tt = 0:(1/fs):dur;
if (keynum == 0)
xx = zeros(1, length(tt)); % pause if no note
else
freq = 440*2^((keynum-49)/12);
if (voicenum == 1)
f = freq*[1 2 3 4]';
A = [1 1/2 1/4 1/8];
elseif (voicenum == 2)
f = freq*[1 3 5]';
A = 0.8*[1 1/2 1/4];
elseif (voicenum == 3)
f = 1.5*freq*[1 2 3 4]';
A = [1 1/2 1/4 1/8];
end
xx = A*cos(2*pi*f*tt);
% ADSR Envelope
if( dur>0.15 )
E = interp1([0,0.05,0.1,dur-0.05,dur],[0,1,0.9,0.8,0],tt);
elseif( dur>0.10 )
E = interp1([0,0.05,dur-0.05,dur],[0,1,0.8,0],tt);
else
E = interp1([0,0.05,dur],[0,1,0],tt);
end
% multiply xx by ADSR envelope
xx = xx.*E;
end
end

Sign in to comment.

Answers (0)

Tags

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!