How to play a note
Show older comments
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)
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
on 21 Oct 2021
Edited: Walter Roberson
on 21 Oct 2021
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?
tom cohen
on 21 Oct 2021
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)';
tom cohen
on 22 Oct 2021
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);
tom cohen
on 24 Oct 2021
Categories
Find more on Audio I/O and Waveform Generation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


