Hallo, ich erzeuge Töne mit Hilfe einer Sinustabelle und gebe diese mit einem Abdac zum Verstärker. Jetzt möchte ich eine ADSR Hüllkurve integrieren damit das etwas vernünftig klingt. Hat jemand Tips, Code oder Anleitung wie man sowas in C implementiert(möglichst einfach)?
Du musst nur deinen Sinus mit der ADSR-Kurve multiplizieren bevor du ihn zum DAC gibst wobei die Kurve dann ein Gleitkommawert von 0 bis 1 ist. Wenn du bei integer bleiben willst dann dividiere den Sinus durch (255 - ADSR_Wert) bei 8Bit bzw. (65535 - ADSR_Wert) bei 16Bit usw. Code könnte dann ungefähr so aussehen:
1 | uint16 u16_ADSR_Wert; //aktueller Wert zum "dividieren" mit dem sinus |
2 | uint16 au16_ADSR_Dauer[4]; //Dauer der Abschnitte |
3 | uint16 au16_ADSR_Hoehe[2]; //Höhe des A uns S Abschnittes |
4 | boolean b_taste; //true wenn taste gedrückt wurde |
5 | |
6 | typedef enum |
7 | {
|
8 | ph_Nix
|
9 | ph_A
|
10 | ph_D
|
11 | ph_S
|
12 | ph_R
|
13 | }EN_PHASEN |
14 | |
15 | EN_PHASEN en_phase; |
16 | |
17 | void Timer_1_ms(void) |
18 | {
|
19 | static uint16 u16_time; |
20 | if( b_taste == TRUE ) |
21 | {
|
22 | //Tastendruck verarbeiten
|
23 | en_phase = ph_A; |
24 | u16_time = 0; |
25 | b_taste = FALSE; |
26 | }
|
27 | |
28 | if( en_phase == ph_A ) |
29 | {
|
30 | if( u16_time < au16_ADSR_Dauer[0] ) |
31 | {
|
32 | u16_ADSR_Wert = ( au16_ADSR_Hoehe[0] / au16_ADSR_Dauer[0] ) * u16_time; |
33 | u16_time++; |
34 | }
|
35 | else
|
36 | {
|
37 | //nächste Phase
|
38 | en_phase = ph_D; |
39 | u16_time = 0; |
40 | }
|
41 | }
|
42 | elseif( en_phase == ph_D ) |
43 | {
|
44 | if( u16_time < au16_ADSR_Dauer[1] ) |
45 | {
|
46 | u16_ADSR_Wert = ( (au16_ADSR_Hoehe[0]-au16_ADSR_Hoehe[1]) / au16_ADSR_Dauer[1] ) * (au16_ADSR_Dauer[1]-u16_time) + au16_ADSR_Hoehe[1]; |
47 | u16_time++; |
48 | }
|
49 | else
|
50 | {
|
51 | //nächste Phase
|
52 | en_phase = ph_S; |
53 | u16_time = 0; |
54 | }
|
55 | }
|
56 | elseif( en_phase == ph_S ) |
57 | {
|
58 | if( u16_time < au16_ADSR_Dauer[2] ) |
59 | {
|
60 | u16_ADSR_Wert = au16_ADSR_Hoehe[1]; |
61 | u16_time++; |
62 | }
|
63 | else
|
64 | {
|
65 | //nächste Phase
|
66 | en_phase = ph_R; |
67 | u16_time = 0; |
68 | }
|
69 | }
|
70 | elseif( en_phase == ph_R ) |
71 | {
|
72 | if( u16_time < au16_ADSR_Dauer[3] ) |
73 | {
|
74 | u16_ADSR_Wert = ( au16_ADSR_Hoehe[1] / au16_ADSR_Dauer[3] ) * (au16_ADSR_Dauer[3]-u16_time); |
75 | u16_time++; |
76 | }
|
77 | else
|
78 | {
|
79 | //nächste Phase
|
80 | en_phase = ph_Nix; |
81 | u16_time = 0; |
82 | }
|
83 | }
|
84 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.