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 Measurements and Spatial Audio 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!


