|
Autor |
Sinuswellen um Noten auszugeben, die am Ende Beethovens Elise spielen. |
|
rapiz
Ehemals Aktiv  Dabei seit: 26.11.2019 Mitteilungen: 108
 | Themenstart: 2020-01-31
|
Moin, bin grad am Verzweifeln mit matlab
Soll wie im Titel beschrieben ein Skript erstellen, dass Pianotöne spielen kann. Also Noten.
Habe folgendes Skript programmiert, dessen Tonausgabe aber keinen gewünschten ähnlichen Ton ausgibt, sondern ein Rauschen, das immer gleich klingt.
Kann mir wer sagen, woran es liegt und wie ich dies ausbessere?
\sourceon matlab
sound(createWaveform(1000,8000,1,10),8000);
%disp(testit(800,2,4,01));
function [sinusoid] = createWaveform(frequency,fs,duration,A)
n = linspace(0,duration-1/fs,duration*fs);
sinusoid2=linspace(0,duration-1/fs,duration*fs);
for i = 1:duration*fs
sinusoid2(1,:) = A*cos(2*pi*frequency*n(i)*1/fs+
((2*pi).*rand(1,1)));
end
sinusoid=sinusoid2;
end
function [tone] = note(keynum,relDuration,fullDuration,fs)
basetone = 440;
frequency = basetone * nthroot(2,12)^(keynum-49);
[tone]=createWaveform(frequency,fs,relDuration*fullDuration,1);
end
\sourceoff
|
Profil
|
rlk
Senior  Dabei seit: 16.03.2007 Mitteilungen: 11603
Wohnort: Wien
 | Beitrag No.1, eingetragen 2020-01-31
|
Hallo rapiz
\quoteon(2020-01-31 22:01 - rapiz im Themenstart)
\sourceon Matlab
\numberson
sound(createWaveform(1000,8000,1,10),8000);
%disp(testit(800,2,4,01));
function [sinusoid] = createWaveform(frequency,fs,duration,A)
n = linspace(0,duration-1/fs,duration*fs);
sinusoid2=linspace(0,duration-1/fs,duration*fs);
for i = 1:duration*fs
sinusoid2(1,:) = A*cos(2*pi*frequency*n(i)*1/fs+
((2*pi).*rand(1,1)));
end
sinusoid=sinusoid2;
end
function [tone] = note(keynum,relDuration,fullDuration,fs)
basetone = 440;
frequency = basetone * nthroot(2,12)^(keynum-49);
[tone]=createWaveform(frequency,fs,relDuration*fullDuration,1);
end
\sourceoff
\quoteoff
der Fehler ist in Zeile 8: Du berechnest den i-ten Wert des Tons, speicherst ihn aber nicht in dem entsprechenden Element des Vektors sinusoid2 . Das Argument des Kosinus scheint mir auch nicht richtig zu sein: dem Index $i\in\IN$ entspricht die Zeit $t_i=i/f_s$ und der Winkel $\omega t_i=2\pi f t_i$. Warum addierst Du noch eine zufällige Phase?
Servus,
Roland
|
Profil
|
rapiz
Ehemals Aktiv  Dabei seit: 26.11.2019 Mitteilungen: 108
 | Beitrag No.2, vom Themenstarter, eingetragen 2020-02-01
|
Danke, hab es inzwischen ausgebessert indem ich neu angefangen habe.
Habe das i nicht benutzt, fuck klar, dass es nichts wird.
Zur Phase, die soll ich so benutzen.
Habe inzwischen dies und bin dabei eine ADSR Hülle einzubinden.
Verstehe da gerade nicht warum mein E Array nicht die Werte von 0-1 für die Attack Phase annimmt.
Teile matlab mit es soll für den i-ten Wert von E meine Berechnung vornehmen, die anscheinend ignoriert wird und es wird 0 benutzt.
Irgendwas scheint bei matlab mit den loops anders zu sein.
\sourceon matlab
%sound(createWaveform(1000,8000,1,1));
sound(note(44,1/2,1,8000));
function [sinusoid] = createWaveform(frequency,fs,duration,A)
Fs = fs;
dt = 1/Fs;
t = (0:dt:duration)';
Fc = frequency; % hertz
sinusoid = A.*cos(2*pi*Fc*t+(2*pi).*rand(1,1));
end
function [tone] = note(keynum,relDuration,fullDuration,fs)
basetone = 440;
frequency = basetone * nthroot(2,12)^(keynum-49);
tone=createWaveform(frequency,fs,relDuration*fullDuration,1).*envel(relDuration,fullDuration,fs);
end
% [E] = envel(relDuration,fullDuration,fs)
function[E] = envel(relDuration,fullDuration,fs)
dt = 1/fs;
dr=fullDuration*relDuration;
t = (0:dt:dr)';
E= (0:dt:dr)';
S=0;
for i = 1:round(1/8*length(t)) %Attack
E(i)= 1/(round(1/8*length(t)))*i;
end
X=1; %Delay
for i = round(length(t)*1/8) : round(length(t)*3/8)
E(i)= X-1/10*(relDuration*fullDuration*fs*1/8);
X=E(i);
end
F=X; %Sustain
for i = round(length(t)*3/8) : round(length(t)*6/8)
E(i)= F;
end
Y=F; %Restain
for i = round(length(t)*6/8) : round(length(t)*8/8)
E(i)= Y-F/(relDuration*fullDuration*1/8);
end
E
1/(round(1/8*length(t)))
end
\sourceoff
|
Profil
|
rlk
Senior  Dabei seit: 16.03.2007 Mitteilungen: 11603
Wohnort: Wien
 | Beitrag No.3, eingetragen 2020-02-03
|
Hallo rapiz,
ich würde die Ausdrücke round(length(t)*k/n) einmal berechnen lassen und in Variablen speichern, die Du dann für die Anfangs- und Endwerte in den Schleifen verwenden kannst.
So wird der Code übersichtlicher und Du kannst im Debugger leichter prüfen, ob die Werte Deinen Erwartungen entsprechen.
Servus,
Roland
PS: D und R in ADSR stehen für Decay und Release
https://de.wikipedia.org/wiki/ADSR
|
Profil
|
rapiz hat die Antworten auf ihre/seine Frage gesehen. |
|
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2023 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen. Lesen Sie die
Nutzungsbedingungen,
die Distanzierung,
die Datenschutzerklärung und das Impressum.
[Seitenanfang]
|