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?
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:
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?
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...
@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 :-)
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
staticuint8_ti,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.
> 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?
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.