ADSR Funktion

Gast #2508743
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
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.