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));

Réponses (1)

Dave B
Dave B le 21 Oct 2021
Modifié(e) : Dave B le 21 Oct 2021

0 votes

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 commentaires

tom cohen
tom cohen le 21 Oct 2021
Modifié(e) : Walter Roberson le 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 le 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
tom cohen le 21 Oct 2021
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).
Dave B
Dave B le 22 Oct 2021
Modifié(e) : Dave B le 22 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
tom cohen le 22 Oct 2021
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);
tom cohen
tom cohen le 24 Oct 2021
that's great, thank you very much for your help :)

Connectez-vous pour commenter.

Catégories

En savoir plus sur Audio I/O and Waveform Generation dans Centre d'aide et File Exchange

Tags

Question posée :

le 21 Oct 2021

Commenté :

le 24 Oct 2021

Community Treasure Hunt

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

Start Hunting!

Translated by