Matroids Matheplanet Forum Index
Moderiert von mire2
Mathematische Software & Apps » Matlab » Sinuswellen um Noten auszugeben, die am Ende Beethovens Elise spielen.
Autor
Universität/Hochschule Sinuswellen um Noten auszugeben, die am Ende Beethovens Elise spielen.
rapiz
Ehemals Aktiv Letzter Besuch: vor mehr als 3 Monaten
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 Letzter Besuch: in der letzten Woche
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 Letzter Besuch: vor mehr als 3 Monaten
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 Letzter Besuch: in der letzten Woche
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.

Wechsel in ein anderes Forum:
 Suchen    
 
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]