How to play a note

Hi, why can't i play this?
fs = 8192;
dt = 1/fs;
L = 1;
L=L*fs;
t = (0:1:L-1)*dt-0.5;
NoteFreq1 = 261.63;
NoteFreq2 = 659.26;
NoteFreq3 = 440;
NoteDuration = 0.25;
NoteSpace =0.1;
Note=abs(t)<=((NoteDuration/2).*cos(2*pi*NoteFreq1*t)+((NoteDuration/2)+ NoteSpace).*cos(2*pi*NoteFreq2*t)+((NoteDuration/2)- NoteSpace).*cos(2*pi*NoteFreq3*t));

Answers (1)

Dave B
Dave B on 21 Oct 2021
Edited: Dave B on 21 Oct 2021
The Note you made is a logical: you're asking where abs(t) is less than or equal to (a bunch of stuff)
If you want to play this logical, you can by just casting it to double:
sound(double(Note))
But I'm not sure if that's what you intended...maybe it was more like:
Note=double(abs(t)<=((NoteDuration/2))) .* cos(2*pi*NoteFreq1*t)+((NoteDuration/2)+ NoteSpace).*cos(2*pi*NoteFreq2*t)+((NoteDuration/2)- NoteSpace).*cos(2*pi*NoteFreq3*t);
Some suggestions:
  • Break out the Note = line into a few variables, it will make it easier to keep track of the ()s
  • plot(Note) to make sure it's what you expect

7 Comments

tom cohen
tom cohen on 21 Oct 2021
Edited: Walter Roberson on 21 Oct 2021
thank you, it's closer. But i'm actually looking for a way to play and plot (in time domain, frequency domain and also dB scale) a 1 second long signal composed of 3 notes (C, E and A). each one (each Frequency) should go for 0.25 seconds with 0.1 sec break between them. after that i need to filter just E and plot it again in time domain. then finely, repeat ALL 3 STEPS for a signal with 10dB snr.
i didn't break the not becouse i don't know how to get the right image (as attached) any other way (that's the plot code i did):
figure(1)
subplot(2,3,1)
plot(t,Note)
ylim([0 1.1])
title({'Input Signal-full'}), xlabel('Time'), ylabel('note')
subplot(2,3,4)
plot(t,Note)
ylim([0 1.1])
xlim([-0.01 0.01])
title({'Input Signal-zoom'}), xlabel('Time'), ylabel('note')
would very much appreciate your help if you have any ideas.
thanks again very much friend.
Dave B
Dave B on 21 Oct 2021
Can you clarify? I think you want to play:
  • C, 0.25s
  • silence, .1sec
  • E, .25s
  • silence, .1sec
  • A, .25s
then...what? repeat with some kind of reduced signal to noise for just the E?
first part is correct, yes (plus the plots).
second part, filter just E (plus plot for the clean E)
third, repeat everything for a signal with 10dB snr (add the snr to the signal in the first part + filter E from that signal).
I can do the first part, with a handful of plots. But I'm still pretty unclear on what the second a third parts mean...I'm sure you have something in mind as a filter for E, and also as a method to add the noise to achieve a 10dB snr...maybe it will be easier with the first bit a little more organized?
There are a bunch of different ways to construct the note train, I think it's way easier to append the vectors than to add them, so that's what I did here. Here's some thoughts about how you might apply your noise and filters given this structure
  • If you wanted to filter notes(2,:), then just notes(2,:)=filtfilt(b,a,notes(2,:)) or whatever filter you want here.
  • If you want to add noise to the whole thing, then just apply whatever is going to add noise to master_y (or separately to each of the signals).
  • If you want to target just those values corresponding to notes(2,:) in the master_y vector (i.e. you want to adjust the second note after building master_y)...the first index is 2869 (numel(t) + numel(silence) + 1) and the last index is 4916 (2*numel(t) + numel(silence) + 1) so you can do master_y(2869:4916) = fitlfilt(b,a,master_y(2869:4916) (or however you want to filter it)
  • Or maybe you meant filter out E from the signal using a bandstop? filtfilt(b,a,master_y) where b and a filter out 600-700Hz? In any case, shouldn't be too difficult to do that now...
fs = 8192;
t = linspace(0,.25,fs*.25);
freq(1) = 261.63;
freq(2) = 659.26;
freq(3) = 440;
notes = nan(1,numel(t));
for i = 1:numel(freq)
notes(i,:) = sin(2*pi*freq(i)*t);
end
silence = zeros(1, round(fs*.1));
master_y = [notes(1,:) silence notes(2,:) silence notes(3,:)];
master_t = linspace(0, numel(master_y)/fs, numel(master_y));
% can do sound(freq(1,:)) for the first note, or sound(master_y) for the
% note-train
The plots were a little ambiguous. I'll do a plot in the time domain, a plot of the spectrum, and a spectrogram. In each case I'll plot each sound and then the train. If you're on a release before 2019b, you can use subplot in place of tiledlayout/nexttile, although you'll lost some of the conveniences...
figure(1);
tcl=tiledlayout(4,1);
for i = 1:3
nexttile
plot(t,notes(i,:))
title(freq(i) + "Hz")
end
nexttile
plot(master_t,master_y)
axis(tcl.Children,'padded')
figure(2);
tcl=tiledlayout(4,1);
for i = 1:3
nexttile
f=fft(notes(i,:));
fx=linspace(0,fs,numel(f));
semilogy(fx(1:end/2),abs(f(1:end/2)));
% replace with pwelch, or whatever you want for spectral density
% estimates
title(freq(i) + "Hz")
end
nexttile
f=fft(master_y);
fx=linspace(0,fs,numel(f));
semilogy(fx(1:end/2),abs(f(1:end/2)));
ylim(tcl.Children,[10^-1 10^4])
xlim(tcl.Children,[0 fs/2])
figure(3)
tcl=tiledlayout(4,1);
for i = 1:3
nexttile
[s,y,x]=spectrogram(notes(i,:),256,64,[],fs);
imagesc(x,y,10*log10(abs(s)))
title(freq(i) + "Hz")
caxis([0 20])
end
nexttile
[s,y,x]=spectrogram(master_y,256,64,[],fs);
imagesc(x,y,10*log10(abs(s)))
caxis([0 20])
axis(tcl.Children,'xy')
ylim(tcl.Children,[0 1000]) %might as well zoom in a bit?
colormap hot
c=colorbar;
c.Layout.Tile='east';
c.Label.String = 'Power (dB)';
wow yes, that's exactly what i wanted for the first part!
thank you so very much for your time and effort, my friend.
for the filter part, i want to extract E from the loop, apply any filter (or how many) and plot in time domain.
it's like the third optiion you've mentioned above i think.. if possible, could you please write the right code for me? i don't know how to manipulate loops very well just yet..
thanks again, i appreciate your help very much.
No problem, I'm not sure what else I can add here, you can grab a chunk of y based on the index, and then filter it and put it back in (?):
fs = 8192;
t = linspace(0,.25,fs*.25);
freq(1) = 261.63;
freq(2) = 659.26;
freq(3) = 440;
notes = nan(1,numel(t));
for i = 1:numel(freq)
notes(i,:) = sin(2*pi*freq(i)*t);
end
silence = zeros(1, round(fs*.1));
master_y = [notes(1,:) silence notes(2,:) silence notes(3,:)];
master_t = linspace(0, numel(master_y)/fs, numel(master_y));
[b,a] = butter(8, [500 800]/(fs/2), 'stop');
segment_start = numel(t) + numel(silence) + 1;
segment_stop = 2*numel(t) + numel(silence) + 1;
master_y(segment_start:segment_stop)=filtfilt(b,a,master_y(segment_start:segment_stop));
plot(master_t,master_y);
that's great, thank you very much for your help :)

Sign in to comment.

Categories

Find more on Audio I/O and Waveform Generation in Help Center and File Exchange

Tags

Asked:

on 21 Oct 2021

Commented:

on 24 Oct 2021

Community Treasure Hunt

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

Start Hunting!