Forum: Mikrocontroller und Digitale Elektronik Tonfrequenzen (Noten) erzeugen mit tiny45 in C


von Jochen (Gast)


Lesenswert?

Ich möchte eine Melodie abspielen, aber ich verstehe nicht, wie ich die 
Töne genau erzeugen kann.
Ich bin soweit dass ein Sinus mit dem schnellen PWM Modus von einem 
tiny45 @ 8MHz (als DAC) mit 64 Schritten erzeugt wird.
Dann müssen die Sinuswerte mit dem 64fachen der Tonfrequenz in das PWM 
Register geladen werden.

Wenn der Tonbereich von A3-A5 also 220-880Hz gehen soll, heisst das für 
den Interrupt 14080Hz (71.02µs) bis 56320Hz (17.75µs).
In dem Bereich liegen 15 Noten mit einer Auflösung von 0.01Hz.
Wenn der Timer mit 1MHz betrieben wird reicht es nicht (1µs), mit 8MHz 
läuft er bei 32µs über.

Wie macht man das?

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Es passt nicht genau zur Frage, aber hier gabs mal einen Thread zum 
Thema Noten in Halbtonschritten berechnen:
Beitrag "Hochzahlen?"

von Jochen (Gast)


Lesenswert?

Interessant, danke.

von Jack B. (jackbraun)


Lesenswert?

Vielleicht ist dieses Programm für Dich interessant:

http://elm-chan.org/works/mxb/report_e.html

von Jochen (Gast)


Lesenswert?

Da steckt anscheinend genau drin, was ich brauche! Leider kann ich nicht 
richtig nachvollziehen, wie es gemacht wird, da ich praktisch keine 
Asm-Erfahrung habe.

Anscheinend verwendet er einen 32kHz Interrupt, um die Frequenzen zu 
erzeugen . Aber wie kommt er bei 16MHz Takt und einem Compare-Wert von 
62 auf 32kHz?

Wie er die Töne erzeugt, verstehe ich leider auch nicht:
1
;--------------------------------------------------------------------;
2
; Pitch number to angular speed conversion table
3
;--------------------------------------------------------------------;
4
;Since sustain area of wave table, a cycle of fundamental frequency, is sampled
5
;in 128 points, the base frequency becomes 32000/128 = 250 Hz. The wave table
6
;lookup pointer, 16.8 fraction, is increased every sample by these 8.8 fractional
7
;angular speed values.
8
9
tbl_pitch: ;  A     B     H     C    Cis    D    Dis    E     F    Fis    G    Gis 
10
  .dw  225,  239,  253,  268,  284,  301,  319,  338,  358,  379,  401,  425 ; 220Hz..
11
  .dw  451,  477,  506,  536,  568,  601,  637,  675,  715,  758,  803,  851 ; 440Hz..
12
  .dw  901,  955, 1011, 1072, 1135, 1203, 1274, 1350, 1430, 1515, 1606, 1701 ; 880Hz..
13
  .dw 1802, 1909, 2023, 2143, 2271, 2406, 2549, 2700, 2861, 3031, 3211, 3402 ; 1760Hz..
14
  .dw 3604, 3818, 4046, 4286, 4542, 4812, 5098, 5400         ; 3520Hz

In meinem Fall bräuchte ich ja nur den Sustain-Table mit (hier: 128) 
Sinus-Werten.
Aber wie macht er es - springt er durch die Tabelle (läßt Werte aus), 
oder spielt er sie unterschiedlich schnell ab?

Ich vermute, da er mit 32kHz Sampling Frequenz auskommt, und anscheinend 
3kHz erzeugen kann, muss er wohl Werte auslassen.
Leidet da nicht das Signal drunter? Ich dachte, man spielt immer alle 
Werte ab, und das mit einer variablen Geschwindigkeit..

Kann mir das jemand erklären bitte?

von Jochen (Gast)


Lesenswert?

Ich habe einen "Streit" zum Thema Interruptfrequenz vs. Schrittweite 
gefunden: Beitrag "erzeugen eines sinus mit variabler frequenz"

Ich kann mir aber immer noch nicht vorstellen, wie beim Springen durch 
die Tabelle genaue Frequenzen erzeugt werden können, es sind ja keine 
halben Schritte möglich. Sollten dann die umliegenden Werte gemittelt 
werden?

Speicherintensiv ist die Methode, für jeden Ton eine eigene Sinustabelle 
zu verwenden.

Aber eigentlich brauche ich ja nur jemanden, der mit elm-chans prinzip 
kurz erläutert...

von Jochen (Gast)


Lesenswert?

Hier vielleicht die Erklärung:

Beitrag "Re: Tonausgabe Attiny26?"

von TheMason (Gast)


Lesenswert?

@jochen

die ganze geschichte beruht auf dem dds. es wird einfach in 
regelmässigen abständen (samplerate) ein bestimmter wert auf eine 
variable addiert und der überlauf (also das kippen des höchstwertigen 
bits) gibt deine grundfrequenz an.
durch abschneiden mehrerer Bits erhälst du eine "position" innerhalb der 
wellenform (sozusagen skaliert auf die anzahl der bits die du 
abgeschnitten hast). diese kannst du nun auf eine sius oder sonstwelche 
tabelle "mappen" und erhälst einen wert den man per pwm (sollte 
sinnigerweise in einem vielfachen der samplerate liegen) "analog" 
ausgibt.
das eigentlich interessante an dds ist das der vorgegebene inkrement 
linear der freuenz entspricht (bis zur hälfte der wiedergabefrequenz 
bzw. samplerate).

die tabelle ist jetzt (so wie ich es verstanden habe) nur der 
inkrement-wert (passend zur jeweiligen note).


du selbst hüpfst nur noch in der tabelle herum um deine melodie zu 
erzeugen :-)


gruß
rene

ps. hoffe ich habe die problematik richtig verstanden :-)

von Jochen (Gast)


Lesenswert?

Vielen vielen Dank für die Erklärung, jetzt komme ich garantiert weiter!

weitere Links:

http://de.wikipedia.org/wiki/Direct_Digital_Synthesis

"Re: Tonausgabe Attiny26?"
Beitrag "Re: Tonausgabe Attiny26?"

"direkte digitale Synthese"
Beitrag "direkte digitale Synthese (DDS, NCO)"

Unter "3.1.1. Funktionsberechnung" auf Seite 6 der Projektbeschreibung 
von 
http://www.mikrocontroller.net/wiki/Projekt_Digitaler_Funktionsgenerator 
wird man weiterhin fündig.

"A Technical Tutorial on Digital Signal Synthesis" Analog Devices (PDF)
http://www.analog.com/UploadedFiles/Tutorials/450968421DDS_Tutorial_rev12-2-99.pdf

Precision Sine-Wave Tone Synthesis Using 8-Bit MCUs
http://www.freescale.com/files/microcontrollers/doc/app_note/AN1771.pdf

"AN1222: Arithmetic Waveform Synthesis with the HC05/08 MCUs" Freescale 
(PDF)
http://www.freescale.com/files/microcontrollers/doc/app_note/AN1222.pdf

von Christoph H. (Gast)


Lesenswert?


von Jochen (Gast)


Lesenswert?

Ein paar Erkenntnisse zu ELM-CHANs Umsetzung:

16MHz PLL Clock
Timer0 im CTC Mode, clk_IO/8
Comparewert von OCR0A, 62 -> 32258.0645 Hz
128 Werte für die Dauerton-Wellenform (sustain)

> Der Clou ist: eine Sinus-Tabelle z.B. mit 256 Einträgen.
> Der Zugriff auf  diese Tabelle geschieht mit einem Pointer, der ein
> Vorkomma- und ein Nachkomma-Byte hat.
> Wir wollen z.B. 440 Hz erzeugen, die Samplefrequenz sei 10 kHz, also
> habe ich 10000 / 440 = 22,7272 Samples für eine Sinusvollwelle.
> also addiere ich in das Nachkommabyte jedesmal 256*0,7272=186,1632 ->
> 186  und dann mit Carry die 22 in das Vorkommabyte, das dann als Index
> in die Tabelle zeigt.
> Die genaue Frequenz ist 10000/(22+186/256)=440,01375 Hz.

Ich habe jetzt versucht, das mal umzusetzen:

8MHz / 8 OCR0A=31

440 Hz / 32.258kHz/128 =  1.74592 -> 1
0.74592 * 256 = 190.95 -> 191

Das entspricht etwa dem 16.8 Wert für A4 in tbl_pitch (mg.asm:267)
1
ISR(TIM0_COMPA_vect)
2
{
3
  static uint8_t i,f;
4
  
5
      if(f+191 >=255)
6
      {
7
        i++;
8
      }
9
      f+=191;
10
  
11
        if ((i + 1) >= WTS)
12
      {
13
        i = i + 1 - WTS;
14
      }
15
      else
16
      {
17
        i = i + 1;
18
      }
19
      
20
  OCR1A = sine[i];
21
22
}

Mit der nur begrenzt vorhandenen Messtechnik stelle ich einen Fehler von 
5% zu 440Hz fest, und es gibt leichte Schwankungen der Frequenz.

Mit OSCCAL läßt sich der interne Oszillator etwas justieren, aber nur 
verhältnismässig grob.  Also evtl. lieber einen Quarz benutzen.

Um also Teilschritte in der Wellentabelle zu gehen, obwohl nur 
Integer-Werte möglich sind, wird stattdessen gelegentlich ein 
zusätzlicher Schritt eingefügt.

von Jochen (Gast)


Lesenswert?

> Um also Teilschritte in der Wellentabelle zu gehen, obwohl nur
> Integer-Werte möglich sind, wird stattdessen gelegentlich ein
> zusätzlicher Schritt eingefügt.
Korrektur: ... gelegentlich die Schrittweite vergrößert!

Könnte mir jemand sagen, in welchem Format die Melodie gespeichert ist 
und wie das Abspiel-Timing funktioniert?

von Peter (Gast)


Lesenswert?

Nochmals ein interessantes, überschaubares und gut strukturiertes 
Projekt zum Thema Musik und Töne...

http://www.microsyl.com/doorbell/doorbell.html

von Jochen (Gast)


Lesenswert?

Stimmt, er benutzt ja auch DDS.

Welche Rolle spielt bloß bei Chan der kontinuierlich erhöhte 2. Wert aus 
einem Datensatz der score-tabelle? Ich nehme an, dass der erste die 
Tondauer bestimmt.

von Jochen (Gast)


Lesenswert?

Quatsch! -> Beitrag "Sequencer Prinzip ELM - Wavetable Melody Generator (ASM)"

Microsyl verwendet anscheinend nur ganzzahlige Schrittweiten ohne 
Korrektur.

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
Noch kein Account? Hier anmelden.