Danke für die Links. Ich muss mich da mal einlesen.
Das andere Eingabeformat hab ich jetzt programmiert.
Auszug aus meinem Konverter, der leider noch nicht richtig funktioniert:
1 | * HEADER
|
2 | * Anzahl Kanäle (1 - 255)
|
3 | * Anzahl der Noten/Befehle von Kanal 1-x (1 - 65535)
|
4 | *
|
5 | * DATA
|
6 | * Alle Noten/Befehls - Byte von Kanal 1-x
|
7 | *
|
8 | *
|
9 | * Beispiel
|
10 | * 2 Kanäle
|
11 | * 3 Noten/Befehle im 1. Kanal
|
12 | * 1 Noten/Befehle im 2. Kanal
|
13 | * a 1. Note/Befehl des 1. Kanals
|
14 | * b 2. Note/Befehl
|
15 | * c 3. Note/Befehl
|
16 | * d 1. Note/Befehl des 2. Kanals
|
17 | *
|
18 | * entspricht {2,3,1,a,b,c,d}
|
Mein Konverter baut gerade völligen Mist, deshalb sind im MidiTest nur
12 Töne aus Handarbeit. Gibt es eingentlich ein
Opensource-Midiconverter/Analyser?
Wie viel Kanäle haltet ihr auf einem Attiny für realistisch? Ich finde
das wird schon ein bisschen knapp: Mit einem Bauratenquarz mit 22.12Mhz
kommt man auf 22.12Mhz / 44100 = ~500 Takte
Da kann man den PWM-Channel 2 mal durchlaufenlassen. In 500 Takten muss
man dann das hier für alle Kanäle neuberechnet haben:
1 | unsigned char GetChannel(unsigned char i)
|
2 | {
|
3 | if(channel[i].pos >= channel[i].len)
|
4 | return 128;
|
5 | if(++channel[i].tonepos >= channel[i].tonelen)
|
6 | {
|
7 | channel[i].tonepos = 0;
|
8 | channel[i].freqpos = 0;
|
9 | //Neuer Ton
|
10 | unsigned char value;
|
11 | while(!IsTone(value = array[++channel[i].pos]))
|
12 | {
|
13 | switch(value & 0xC0)
|
14 | {
|
15 | case 0xC0: channel[i].tonelen = (1 << (7 - (value & 0x07))) * 44100 / 128 * 2;
|
16 | printf("Channel %d (%d / %d): New Tone-Len: %d\n",i,channel[i].pos, channel[i].len, channel[i].tonelen);
|
17 | break;
|
18 | default: printf("Channel %d (%d / %d): Error: Unknown command: %d\n",i,channel[i].pos, channel[i].len, value & 0xC0);
|
19 | };
|
20 | }
|
21 |
|
22 | channel[i].freq = Freq[array[channel[i].pos]];
|
23 | printf("Channel %d (%d / %d): New Tone: %d\n", i,channel[i].pos, channel[i].len,array[channel[i].pos]);
|
24 | }
|
25 | if(++channel[i].freqpos >= channel[i].freq)
|
26 | channel[i].freqpos = 0;
|
27 | else
|
28 | {
|
29 | if(channel[i].freqpos > channel[i].freq / 2)
|
30 | return 255 - channel[i].tonevol;
|
31 | return channel[i].tonevol;
|
32 | }
|
33 | }
|
Für den µC werd ich natürlich versuchen es noch ein bisschen zu
optimieren. Wahrscheinlich muss man es am Ende sowieso in Asm umsetzen.