Degenerator DIY Sampler/Synthesizer (Tubeohm)

Re: AVR Synthesizer "WAVE 1"

Hallöchen..

Gestern habe ich die Bauteile für meinen Shruthi Synthesizer bekommen. Da ich zu den ungeduldigen Menschen zähle, habe ich eine Nachtschicht eingelegt und den Shruthi zusammen gelötet. So in den frühen Morgenstunden wäre ich fast mit dem Lötkolben in der Hand eingeschlafen und bin dann doch ins Bett gegangen.. Augenzwinkern

Mein Shruthi Synthesizer
Shruthi_12.jpg


Dank der guten Dokumentation und Lötanleitung auf der Mutable Instrument Website ( http://mutable-instruments.net/shruthi1 ) ist der Shruthi sehr einfach und leicht zu löten und schnell zusammenzubauen. Beim Bestellen der Bauteile sollte man beachten, das es unterschiedliche Stücklisten für verschieden Lieferanten wzB Mouser oder Reichelt gibt. Ich habe mich für Reichelt entschieden, da dieser Lieferant kostengünstiger ist. Ein kleines Problem gabs bei der Bestellung der Tasten. Die Original Tasten gabs bei Reichelt nicht und ich musste dafür andere Tasten nehmen. Bei Mouser bekommt man die Original Tasten und die anderen Bauteile problemlos geliefert.

Stückliste Reichelt: https://secure.reichelt.de/index.html?& ... ROVID=2084

Stückliste Mouser: https://www.mouser.de/ProjectManager/Pr ... dcda87764c

Dank meiner langjährigen Lötkünste war der Shruthi schnell zusammengelötet und betriebsbereit. Beim Flashen der aktuellen Firmware über ATMEL STUDIO hatte ich ein kleines Problem. Die Voreinstellung für die PDI Clock-Rate von 1MHz für den Mikrocontroller ATmega644P muss im Menü auf 125KHz herunter gesetzt werden, da sonst der ATmega644P nicht erkannt wird..

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallöchen

So.. am Wochenende hab ich mal wieder fleißig am Synth programmiert und den Step Sequenzer integriert. Er ist noch nich ganz fertig, aber schon lauffähig smile

Noten Symbol: Ausgewählte Midi-Note von 0-127
H ist die Notendauer
V ist die Lautstäke der Note und wird durch einen blauen Balken angezeigt
Roter Punkt bedeutet das der Step aktiv ist. Grau bedeutet ausgeschaltet

Später wirds noch eine Reset und Skip Funktion für jeden Step geben.


Der Step Sequenzer im "Degenerator"
Seq_01.jpg


Das Ganze kann man sich auf Youtube ansehen und anhören. Der Ton kommt von der Webcam und ist leider nicht so prickelnd :sad:


https://www.youtube.com/watch?v=pIb-1a0 ... kyDo6PZ4Cw

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallo..

Ein ganz interessantes Beispiel in Bezug auf Sequenzer ist der K4815 Pattern Generator von Kilpatrick Audio. Beim K4815 handelt es sich um einen Midi Sequenzer ohne Tonerzeugung für den 19 Zoll Einschub. Er besticht durch seine ungewönliche und einfache Bedienung wie ich finde.

K4815 Pattern Generator
K4815P.jpg


Features and Specs
* Eurorack form factor - 20HP width
* 64 LED 8x8 Matrix multi-brightness grid to show patterns and playback
* Clock control via internal clock, or MIDI or analog (5V) clock
* Clock, direction and reset inputs (0V/5V = off/on)
* CV/GATE or X/Y outputs - range: -5V to +5V
* High-precision 12-bit DACs with internal trim adjustment
* Internal MIDI header compatible with future Kilpatrick Audio modules or DIY breakout boards
* Only 30mm deep (including ribbon cables)
* Serial numbers up to 1009500: Requires +/-12V (less than 10mA) and +5V (less than 65mA)
* Serial numbers from 1009501 onward: Requires +12V (80mA) and -12V (less than 10mA)
* 16 pin Doepfer-style power cable used
* Designed and made in Canada using high quality parts.

Website Hersteller: http://www.kilpatrickaudio.com/?p=K4815

Youtube Video: https://www.youtube.com/watch?v=Dlgxvw08R6g

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallo..

Ich bin gerade dabei eine Shuffle Funktion in den Sequenzer einzubauen. Da ich nicht genau weis wie das klingt, habe ich mir das mal beim Shruthi Synthesizer angehört und versucht das grafisch dargestellt.

Shuffle Funktion 4/4 Takt im Shruthi Synthesizer
Shuffle_01.jpg


Die blauen Noten im normalen Takt ohne Shuffle und die roten Noten mit Shuffle

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallo Freunde der Musik

Diese Woche arbeite ich noch ein wenig am Sequenzer in meinem Synthesizer. Folgende Funktionen sind bereits integriert:

16 Steps mit Haltezeit und Velocity
Stepfunktion On, Off, Skip
Manuelle Eingabe der Midi Note oder vom Midi Keyboard
Einstellbare Geschwindigkeit von 30 bis 460 BPM
Transponierung + -2 Oktaven und per Midi Keyboard
Shuffle-Funktion
Velocity für die Modulation zB VCA, VCF oder Oszillator
Sequenzerrichtung Links, Rechts oder Beides
Laden und Speichern von 128 Sequenzen

Der Sequenzer im DeGenerator
Sequencer.jpg


Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallo zusammen..

Hier der Startscreen vom "DEGENERATOR" nach dem Einschalten.

Bin gerade dabei die Wellenformen vom internen Flashspeicher auf die SDCARD auszulagern
damit ich 32KByte mehr Speicherplatz für den Programmcode bekomme.
Die Wellenformen werden nach dem Systemstart in das 1MByte SRAM geladen.
Durch diese Änderung hat man später die Möglichkeit die Wellenformen einfach gegen andere auszutauschen.

Startscreen "DEGENERATOR"
Degenerator_04.jpg


Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallo.. Ich wieder .. smile

In dieser Woche arbeite ich an der Modulations Matrix im Synthesizer.

Hier ist eine kleine mathematische Formel für die Einstellung der Grenzfrequenz mit Cutoff-Level und Amount-Level.

Code:
// VCF1_CV_IN = VCF1 CV Eingangswert 12Bit von ADSR Generator
// VCF1_CV_OUT = VCF1 CV-Ausgangswert
// VCF1_Amount = Geberstufe 0-127
// VCF1_Cutoff = Geberstufe 0-127

VCF1_CV_Out = ((uint32_t) (128 - VCF1_Amount) * VCF1_CV_IN / 128) + (((uint32_t) VCF1_Amount * VCF1_Cutoff / 128) * VCF1_CV_IN / 128)

Für die LFO Modulation des Filters muss ich noch überlegen wie ich die Formel dafür erweiter.
Der LFO Ausgang hat einen Wert von 0-255.

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallöchen..

Bin jetzt im Endspurt und steh etwas unter "Stress". Arbeite viel an meinem Synthesizer. Aus diesem Grund fallen meine Berichte hier etwas mager aus. Zur Zeit wird eine Frontblende hergestellt damit der "DEGENERATOR" in der CC2 TV Sendung nächste Woche nicht so "nackelich" aussieht. Musste dafür extra noch ein 2.Frontpanel zusammenlöten (siehe Bild). Ein komplettes Gehäuse aus durchsichtigem Kunststoff ist schon in Planung.


2.Frontpanel
2.Frontpanel.jpg


Ach her je.. bin schon ganz aufgeregt Augenzwinkern Hoffentlich funktioniert alles in der TV-Show problemlos und es gibt keinen Vorführeffekt. Ist ja schließlich der Prototyp. Wird schon gut gehen ebueb

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallöchen..

Der "DE:GENERATOR" ist ready for sounding..


Der "DE:GENERATOR"
Degenerator02.jpg

Die Frontplatte ist mal eben schnell gemacht worden und noch nicht so perfekt. Die Display Aussparung stimmt nicht und die Beschriftung fehlt noch.

Gruß Rolf

PS: Morgen gehts ins TV Studio. Bin schon ganz aufgeregt.. grrrr :mrgreen:
 
Re: AVR Synthesizer "WAVE 1"

Ist eine Aufzeichnung und wird erst in 2-3 Wochen auf NRW TV, Tec Time (ehemals Dr.Dish) und im Youtube Channel vom CC2 gesendet.

Hoffentlich hab ich Morgen kein Lampenfieber ;-)

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Der Studiobesuch beim CC2

Hallo liebe Freunde..
Der Studiobesuch beim CC2 war sehr interessant und eine große Freude für mich. Endlich konnte ich den "Urgesteinen" des damaligen WDR Computer Clubs Wolfgang Back und Wolfgang Rudolph leibhaftig die Hände schütteln. Der Heinz war dieses mal leider nicht dabei.

Es ist sehr interessant zu beobachten mit welcher Routine und Gelassenheit und vor allem mit wieviel Humor die beiden Wolfgänge eine TV Sendung machen. Und ich live dabei und mittendrin.. wow.

Von Lampenfieber vor den drei Kameras war bei mir keine Spur mehr als ich mit Wolfgang Rudolph ins Gespräch kam und von den Anfängen meiner Entwicklung am Synthesizer erzählte. Techniker unter sich.. da sind 15 Minuten nix. Die Minuten flogen im Eiltempo an mir vorbei und ich hätte noch Stunden vom Synthesizer, Elektronischer Musik u.a. Dingen erzählen können. Aber da war noch Stefan Krister und der wollte etwas über den 3D Druck erzählen. Dem wollte ich nicht die Show stehlen smile

Hab mal ein paar Fotos aus dem Studio von NRW TV geschossen um zu "beweisen" das ich wirklich da war Augenzwinkern

Fotos CC2 Studiobesuch
Studio_01.jpg

Studio_02.jpg

Studio_04.jpg

Studio_06.jpg

Studio_07.jpg

Studio_08.jpg


Gruß Rolf

PS: Die Toten Hosen habe ich leider nicht mehr getroffen. Die hatten nach uns eine Aufzeichnung im gleichen TV Studio. Schade.. :sad:
 
Re: AVR Synthesizer "WAVE 1"

Interessanter Beitrag...

"Den" Macher kennenzulernen oder auch mal den Andre zu sehen macht euch sympathisch.
Da bin ich schon sehr gespannt auf Teil II.
 
Re: AVR Synthesizer "WAVE 1"

Hallo zusammen !

Ich habe diesen Monat mal wieder etwas Geld in die Hand genommen und mir was schönes und hoffentlich gutes gekauft. Natürlich spreche ich von Hardware. Ich glaube wenn wir Männer freiwillig auf Shopping Tour gehen, dann nur um die neueste Technik einzukaufen. Das macht tierisch viel Spaß :D

Auf ebay habe ich mir ein gebrauchtes "Analog Factory Experience" Midi Keyboard von Arturia gekauft. Leider ist das noch die ältere Version 2.0 ohne After Touch. Durch sein Metallgehäuse und die beiden Holzseitenteile sieht es wertig aus wie ich finde. Es hat 32 gewichtete Tasten und ein gutes Spielgefühl. Außerdem hat es noch 15 Dreh- und Schieberegler um Klangparameter über Midi zu steuern. Das Midi-Keyboard besitzt eine USB-Schnittstelle und eine Midi-Out Buchse. Unter Windows 7 wurde der USB-Treiber automatisch erkannt und ohne Problem installiert.

Arturia Midi Keyboard
Arturia.jpg


Damit ich meinen Synthesizer auch von einem Sequenzer Programm auf meinem Windows 7 PC anspielen kann, benötige ich ein Midi-Interface. Beim Musikhaus Thomann wurde ich fündig und hab mir vom miditech ein 2x2 Midi Interface gekauft. Das besitzt 2x Midi-In und 2x Midi-Out Buchsen und eine USB Schnittstelle. Auch das Gerät wurde unter Windows 7 reibungslos erkannt und automatisch installiert. Mein Sequenzer Programm "StEP4free" arbeitet problemlos mit dem Midi Interface zusammen.

2x2 Midi Interface von miditech
midiface.jpg


So das wars mal wieder. Zur Zeit programmiere ich fleißig an der seriellen Datenübertragung zwischen Frontpannel und Hauptboard vom Synthesizer.

Lieben Gruß aus Wuppertal. Der Rolf smile
 
Re: AVR Synthesizer "WAVE 1"

Hallo..

Diese Woche arbeite ich noch einmal am Frontpannel. Wegen der ca. 20cm langen 8Bit Datenleitungen vom Prozessorport zum Display kommt es gelegentlich zu Störungen auf dem Display. Die Daten werden mit einer Geschwindigkeit von 16Mhz übertragen. Ich habe mir überlegt für die Display-Ansteuerung einen eignen ATmega328P Prozessor auf dem Frontpannel einzusetzen. Dadurch werden die Datenleitung zum Display sehr kurz und Störungen bei der Datenübertragung vermieden. Die Datenübertragung vom ATxmega128 Hauptprozessor zum Display-Prozessor erfolgt dann über den schnellen SPI Bus der Prozessoren.

Noch ein Vorteil hätte diese Änderung. Der Hauptprozessor würde mit der aufwendigen Berechnung für Lienen, Rechtecken und Textzeichen auf dem Display entlastet werden. Das würden dann der Display-Prozessor übernehmen. Die Abfrage der Taster und Encoder könnte der Display Prozessor ebenfalls übernehmen.


Altes Prozessorbaord und Frontpannel
MCU_Board2.2.jpg



Neues Frontpannel mit ATmega328 Prozessor
Frontpannel_30.jpg


Die Hardware ist gelötet. Wie man auf dem Foto sehen kann funktioniert das Display mit dem neuen ATmega328 Prozessor schon. Die Grafik- und Textroutinen konnte ich ohne ohne Anpassung vom ATXmega128 auf dem ATmega328 übernehmen. Einziger Unterschied ist die Geschwindigkeit mit der die Bits am Ausgabeport gesetzt werden. Der ATmega328 benötigt zum setzen eines Portbits 2 Taktzyklen. Der schnellere ATxmega128 brauchte im Vergleich nur einen Prozessortakt dafür.
Ferner kann der ATmega328 unter 3.3 Volt Betriebspannung nur mit 12Mhz betrieben werden. Unter 5 Volt kann man ihn dagegen mit einer maximalen Taktrate von 20MHz befeuern. Aber 12MHz sollten für die Grafikausgabe und Tastenabfrage ausreichen.

Neues Frontpannel in Aktion
FP_Blau_01.jpg


Encoder mit Led-Ring
Im Moment überlege ich noch, ob ich für die 4 Eingabe-Encoder unterm Display noch jeweils einen farbigen LED-Ring mit 16 Leds spendiere. Blau wäre ganz schön. Ich denke das wertet das Gehäuse Designe noch etwas auf und bringt mehr Farbe in die Musik. Solche fertigen Led-Ringe mit Ansteuerelektronik gibts im Internet ab 20 Euro. Etwas teuer wenn ihr mich fragt. Das würde dir Frontplatte direkt um 80 Euro teuer machen. Im Prinzip kann manns auch selber machen.
Dazu bräuchte man acht 8Bit-Schieberegister vom Typ 74HC595 und 64 Leds. Bei Sparkfun gibts aber schon fertige Led-Ringe ab ohne Ansteuerelektronik zu kaufen. Ist vielleicht etwas einfacher zu löten beim späteren Bausatz.

Led-Ring mit Ansteuerelektronik
LedRing_01.jpg


Led-Ring ohne Ansteuerelektronik ca. 10 Euro
LedRing_02.jpg


Encoder mit Led-Ring
LedRing_03.jpg


Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallöchen..

Bald ist Urlaubszeit und ich hab kein Geld :heul: ...aber dafür einen Süd-Balkon mit einer neuen großen funkgesteuerten Markise :D

Diese Woche habe ich die Envelope Routinen im Synthesizer verbessert. Die alten Routinen benötigten viel Rechenzeit durch Divisionen und hatten Rundungsfehler. Angeregt durch den Envelope Generator im Shruthi Synthesizer und die großartige Unterstützung von Oliver aus dem Mutable Forum habe ich den Quellcode für meinen Synthesizer angepasst. Dieser besteht im wesentlichen aus einem 16Bit Counter und einer kleinen Tabelle um die Lineare Kurvenform in eine Exponentiale Kurve zu konvertieren.

Code:
//----------------------------------------------------------------
// Variable
//----------------------------------------------------------------

uint16_t phase_;
uint16_t phase_increment;
uint16_t ramp_start_;
uint16_t ramp_end_;
uint8_t  ramp_a_;
uint8_t  ramp_b_;
uint16_t value_;




//-----------------------------------------------------------------
// Envelope Phase
//-----------------------------------------------------------------

if (adsr1_phase == ATTACK)
	{
		// load 7Bit attack_value1 from encoder (0-127) and convert to 16Bit phase_increment
		phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[attack_value1]));
		ramp_start_ = 0;
		ramp_end_ = 65535;
		ramp_a_ = 0;
		ramp_b_ = 255;
		
		envelope();
	}
	else if (adsr1_phase == DECAY)
	{
		// load 7Bit decay_value1 from encoder (0-127) and convert to 16Bit phase_increment
		phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[decay_value1]));
		
		// load 7Bit sustain level from encoder (0-127) and convert to 16Bit phase_increment
		ramp_start_ = pgm_read_word (&(sustain_level[sustain_value1]));
		ramp_end_ = 65535;
		ramp_a_ = 255;
		ramp_b_ = 0;
		
		envelope();
		
		release_level = value_;
	}
	
	else if (adsr1_phase == RELEASE)
	{
		// load 7Bit release_value1 from encoder (0-127) and convert to 16Bit phase_increment
		phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[relaese_value1]));
		ramp_start_ = 0;
		ramp_end_ = release_level;
		ramp_a_ = 255;
		ramp_b_ = 0;
		
		envelope();
	}
	
	if (midi_gate_flag == 0)
	{
		if (adsr1_phase < 3)
		{
			adsr1_phase = RELEASE;
			phase_ = 0;
		}
	}



//-------------------------------------------------------------------------
// Envelope
//-------------------------------------------------------------------------
void envelope(void)
{
	// increment 16Bit env_ramp
	phase_ += phase_increment;

	// check end of attack phase
	if (phase_ < phase_increment)
	{
		// set next envelope phase
		adsr1_phase ++;
		phase_ = 0;
	}

	else
	{
		// interpolate 8Bit env_expo table with 16Bit phase_
		uint8_t step = InterpolateSample(wav_res_env_expo, phase_);
		// calc 16Bit envelope value
		uint16_t ramp_expo =  U8MixU16(ramp_a_, ramp_b_, step);
		value_ = ramp_start_ + ((uint32_t)(ramp_end_ - ramp_start_) * ramp_expo >> 16);
		// set envelope_out
		adsr1_out = value_;
	}
}


//---------------------------------------------------------------------------
// inline function and tables
//---------------------------------------------------------------------------

static inline uint8_t InterpolateSample(
	//const uint8_t* table, uint16_t phase) {
	const uint8_t table[], uint16_t phase) {
	uint8_t result;
	uint8_t work;
	asm(
	"movw r30, %A2"           "\n\t"  // copy base address to r30:r31
	"add r30, %B3"            "\n\t"  // increment table address by phaseH
	"adc r31, r1"             "\n\t"  // just carry
	"mov %1, %A3"             "\n\t"  // move phaseL to working register
	"lpm %0, z+"              "\n\t"  // load sample[n]
	"lpm r1, z+"              "\n\t"  // load sample[n+1]
	"mul %1, r1"              "\n\t"  // multiply second sample by phaseL
	"movw r30, r0"            "\n\t"  // result to accumulator
	"com %1"                  "\n\t"  // 255 - phaseL -> phaseL
	"mul %1, %0"              "\n\t"  // multiply first sample by phaseL
	"add r30, r0"             "\n\t"  // accumulate L
	"adc r31, r1"             "\n\t"  // accumulate H
	"eor r1, r1"              "\n\t"  // reset r1 after multiplication
	"mov %0, r31"             "\n\t"  // use sum H as output
	: "=r" (result), "=r" (work)
	: "r" (table), "r" (phase)
	: "r30", "r31"
	);
	return result;
}

static inline uint16_t U8MixU16(uint8_t a, uint8_t b, uint8_t balance) {
	uint16_t result;
	asm(
	"mul %3, %2"      "\n\t"  // b * balance
	"movw %A0, r0"    "\n\t"  // to sum
	"com %2"          "\n\t"  // 255 - balance
	"mul %1, %2"      "\n\t"  // a * (255 - balance)
	"com %2"          "\n\t"  // reset balance to its previous value
	"add %A0, r0"     "\n\t"  // add to sum L
	"adc %B0, r1"     "\n\t"  // add to sum H
	"eor r1, r1"      "\n\t"  // reset r1 after multiplication
	: "&=r" (result)
	: "a" (a), "a" (balance), "a" (b)
	);
	return result;
}


//-------------------------------------------------------------------------
// Attack increments 16Bit
//-------------------------------------------------------------------------
const uint16_t lut_res_env_portamento_increments[] PROGMEM = {
	
	65535,  18904,  16416,  14304,  12504,  10968,   9647,   8509,
	7525,   6672,   5931,   5285,   4719,   4224,   3788,   3405,
	3066,   2766,   2500,   2264,   2053,   1865,   1697,   1546,
	1411,   1290,   1180,   1082,    993,    912,    839,    773,
	713,    658,    608,    562,    521,    483,    448,    416,
	387,    360,    335,    313,    292,    272,    255,    238,
	223,    209,    196,    184,    172,    162,    152,    143,
	135,    127,    119,    113,    106,    100,     95,     90,
	85,     80,     76,     72,     68,     64,     61,     58,
	55,     52,     50,     47,     45,     43,     41,     39,
	37,     35,     33,     32,     30,     29,     28,     26,
	25,     24,     23,     22,     21,     20,     19,     18,
	18,     17,     16,     16,     15,     14,     14,     13,
	13,     12,     12,     11,     11,     10,     10,      9,
	9,      9,      8,      7,      7,      6,      6,      5,
	5,      4,      4,      3,      3,      2,      2,      1	
};

const uint8_t wav_res_env_expo[] PROGMEM = {
	0,      4,      9,     14,     19,     23,     28,     32,
	37,     41,     45,     49,     53,     57,     61,     65,
	68,     72,     76,     79,     83,     86,     89,     92,
	96,     99,    102,    105,    108,    111,    113,    116,
	119,    121,    124,    127,    129,    132,    134,    136,
	139,    141,    143,    145,    148,    150,    152,    154,
	156,    158,    160,    161,    163,    165,    167,    169,
	170,    172,    174,    175,    177,    178,    180,    181,
	183,    184,    186,    187,    188,    190,    191,    192,
	193,    195,    196,    197,    198,    199,    200,    201,
	202,    203,    205,    206,    206,    207,    208,    209,
	210,    211,    212,    213,    214,    215,    215,    216,
	217,    218,    218,    219,    220,    221,    221,    222,
	223,    223,    224,    225,    225,    226,    226,    227,
	227,    228,    229,    229,    230,    230,    231,    231,
	232,    232,    233,    233,    233,    234,    234,    235,
	235,    236,    236,    236,    237,    237,    238,    238,
	238,    239,    239,    239,    240,    240,    240,    241,
	241,    241,    241,    242,    242,    242,    243,    243,
	243,    243,    244,    244,    244,    244,    245,    245,
	245,    245,    245,    246,    246,    246,    246,    246,
	247,    247,    247,    247,    247,    248,    248,    248,
	248,    248,    248,    248,    249,    249,    249,    249,
	249,    249,    249,    250,    250,    250,    250,    250,
	250,    250,    250,    251,    251,    251,    251,    251,
	251,    251,    251,    251,    251,    252,    252,    252,
	252,    252,    252,    252,    252,    252,    252,    252,
	252,    253,    253,    253,    253,    253,    253,    253,
	253,    253,    253,    253,    253,    253,    253,    253,
	253,    254,    254,    254,    254,    254,    254,    254,
	254,    254,    254,    254,    254,    254,    254,    254,
	254,    254,    254,    254,    254,    254,    254,    255,
	255
};

//-------------------------------------------------------------------------
// Sustain level 16Bit
//-------------------------------------------------------------------------
const uint16_t sustain_level[] PROGMEM = {
	    1,    11,    33,    65,   106,   157,   218,   287,
	    366,   454,   550,   655,   769,   891,  1022,  1162,
	    1310,  1466,  1630,  1803,  1984,  2173,  2370,  2576,
	    2789,  3011,  3240,  3477,  3723,  3976,  4237,  4506,
	    4783,  5068,  5360,  5660,  5968,  6284,  6607,  6938,
	    7277,  7623,  7977,  8338,  8707,  9084,  9468,  9860,
	    10259, 10666, 11080, 11502, 11931, 12367, 12811, 13263,
	    13722, 14188, 14661, 15142, 15630, 16126, 16629, 17139,
	    17657, 18181, 18713, 19253, 19799, 20353, 20914, 21483,
	    22058, 22641, 23231, 23828, 24432, 25043, 25662, 26288,
	    26920, 27560, 28207, 28862, 29523, 30191, 30867, 31549,
	    32239, 32935, 33639, 34350, 35068, 35792, 36524, 37263,
	    38009, 38762, 39522, 40288, 41062, 41843, 42631, 43425,
	    44227, 45036, 45851, 46674, 47503, 48339, 49182, 50033,
	    50889, 51753, 52624, 53502, 54386, 55278, 56176, 57081,
	    57993, 58912, 59837, 60770, 61709, 62655, 63608, 65535
};
 
Re: AVR Synthesizer "WAVE 1"

Hallo ihr Lieben smile

In der vergangenen Woche habe ich an der Modulationsmatrix im Synthesizer gearbeitet. Die Modulationsmatrix wird verwendet um verschiedene Modulationsquellen, etwa LFOs oder Hüllkurvengeneratoren (ENV), mit bestimmten Zielen wie beispielsweise VCA oder Filters zu verknüpfen.

Mögliche Modulationsquellen
LFO1
LFO2
ENV1
ENV2
Velocity
Mod.Wheel
Pitch Wheel
Randomgenerator
Noise
Sequenzer

Mögliche Modulationsziele
Osc1
Osc2
Osc1+Osc2
VCA-Gain
VCF Cutoff
Resonance
Osc-Pan
VCA-Pan
Fx-Pan
LFO1
LFO2


Modulationsmatrix
ModMatrix.jpg


Wenn die Modulationsmatrix fertig ist werde ich ein Video hochladen und die Function genau erklären. Bis dahin lieben gruß aus Wuppertal. Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallöchen..

The new envelope in action
Envelope_22.jpg


Youtube:

Eingebaut:
Code:
[youtube]2nDW_XA8oTU[/youtube]

Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

rolfdegen schrieb:
Mögliche Modulationsquellen
LFO1
LFO2
ENV1
ENV2
Velocity
Mod.Wheel
Pitch Wheel
Randomgenerator
Noise
Sequenzer

Mögliche Modulationsziele
Osc1
Osc2
Osc1+Osc2
VCA-Gain
VCF Cutoff
Resonance
Osc-Pan
VCA-Pan
Fx-Pan
LFO1
LFO2
danke fuer die fleissigen updates - schoen zu sehen, dass du fortschritte machst!

hier mal ein paar anregungen fuer weitere interessante modulationsquellen und -ziele.

quellen:

midi aftertouch
midi cc (soweit nicht schon vergeben)

ziele:

osc1, osc2: weitere parameter neben tonhoehe (wellenform? pulsweite? lfo- und eg-modulationstiefe?)
eg1, eg2: attack, release, decay (meinetwegen auch sustain, aber die zeiten finde ich nuetzlicher)
vcf eg modulationstiefe
vcf lfo modulationstiefe

oder vielleicht noch besser: ganz generell die modulationstiefen der jeweils anderen modulations-busse? also z.b. bus2 kann den 'modulation amount' von bus1 modulieren?

eine weitere moeglichkeit, so etwas flexibel zu loesen, waeren modulationsbusse nach moog-vorbild, wo es fuer jeden bus neben einer modulationsquelle und einem modulationsziel auch noch einen 'controller' gibt, der die modulationstiefe dynamisch bestimmt (die auswahl an controllern waere dann wohl weitgehend identisch mit den modulationsquellen).
 
Re: AVR Synthesizer "WAVE 1"

Hallo bartleby

Danke für die Tips.
Mal schaun was ich noch an Rechenleistung für die Modulation auf dem 8Bitter zur Verfügung habe. Aus diesem Grund habe ich vorab die Envelope Routinen verbessert.


Gruß Rolf
 
Re: AVR Synthesizer "WAVE 1"

Hallöchen..

Es gibt ein kleines Update für den neuen Envelope Generator. Die "wav_res_env_expo" Tabelle dient dem Exponentialen Verlauf der Envelope Kurve und kann auch gegen eine andere Kurvenform ausgetauscht werden. Dadurch ergeben sich sehr interessante Envelope Verläufe. Ferner sind auch mehr als nur vier Envelope-Phasen (ADSR) möglich.

Gruß Rolf

Code:
//----------------------------------------------------------------
// Variable
//----------------------------------------------------------------

uint16_t phase_;
uint16_t phase_increment;
uint16_t ramp_start_;
uint16_t ramp_end_;
uint8_t  ramp_a_;
uint8_t  ramp_b_;
uint16_t value_;


// init envelope
    adsr1_phase = ATTACK;
    adsr2_phase = ATTACK;
    phase_ = 0;

//-------------------------------------------------------------------------
// Envelope Render
//-------------------------------------------------------------------------
void envelope_render(void)
{
  // increment 16Bit env_ramp
  phase_ += phase_increment;

  // check end of attack phase
  if (phase_ < phase_increment)
  {
    // set next envelope phase
    adsr1_phase ++;
    phase_ = 0;
  }
  else
  {
    // interpolate 8Bit env_expo table with 16Bit phase_
    uint8_t step = InterpolateSample(wav_res_env_expo, phase_);
    // calc 16Bit envelope value
    uint16_t ramp_expo =  U8MixU16(ramp_a_, ramp_b_, step);
    value_ = ramp_start_ + ((uint32_t)(ramp_end_ - ramp_start_) * ramp_expo >> 16);
  }
}

//-------------------------------------------------------------------------
// Envelope Phase
//-------------------------------------------------------------------------
void envelope_phase(void)
{  
      
    // init envelope
    adsr1_phase = ATTACK;
    adsr2_phase = ATTACK;
    phase_ = 0;
    
    
  
  // Env 1 (VCA) --------------------------------------------------------
  if (adsr1_phase == ATTACK)
  {
    // load 7Bit attack_value1 from encoder (0-127) and convert to 16Bit phase_increment
    phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[attack_value1]));
    ramp_start_ = 0;
    ramp_end_ = 65535;
    ramp_a_ = 0;
    ramp_b_ = 255;
    
    envelope();
    adsr1_out = value_;
    release_level = value_;
  }
  else if (adsr1_phase == DECAY)
  {
    // load 7Bit decay_value1 from encoder (0-127) and convert to 16Bit phase_increment
    phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[decay_value1]));
    
    // load 7Bit sustain level from encoder (0-127) and convert to 16Bit phase_increment
    ramp_start_ = pgm_read_word (&(sustain_rates[sustain_value1]));
    ramp_end_ = 65535;
    ramp_a_ = 255;
    ramp_b_ = 0;
    
    envelope();
    adsr1_out = value_;
    release_level = value_;
  }
  
  else if (adsr1_phase == RELEASE)
  {
    // load 7Bit decay_value1 from encoder (0-127) and convert to 16Bit phase_increment
    phase_increment = pgm_read_word (&(lut_res_env_portamento_increments[relaese_value1]));
    ramp_start_ = 0;
    ramp_end_ = release_level;
    ramp_a_ = 255;
    ramp_b_ = 0;
    
    envelope();
    adsr1_out = value_;
  }
  
  if (midi_gate_flag == 0)
  {
    if (adsr1_phase < 3)
    {
      adsr1_phase = RELEASE;
      phase_ = 0;
    }
  }
  
  // Env2 (VCF) ---------------------------------------------------------
  
//---------------------------------------------------------------------------
// inline function and tables
//---------------------------------------------------------------------------

static inline uint8_t InterpolateSample(
  //const uint8_t* table, uint16_t phase) {
  const uint8_t table[], uint16_t phase) {
  uint8_t result;
  uint8_t work;
  asm(
  "movw r30, %A2"           "\n\t"  // copy base address to r30:r31
  "add r30, %B3"            "\n\t"  // increment table address by phaseH
  "adc r31, r1"             "\n\t"  // just carry
  "mov %1, %A3"             "\n\t"  // move phaseL to working register
  "lpm %0, z+"              "\n\t"  // load sample[n]
  "lpm r1, z+"              "\n\t"  // load sample[n+1]
  "mul %1, r1"              "\n\t"  // multiply second sample by phaseL
  "movw r30, r0"            "\n\t"  // result to accumulator
  "com %1"                  "\n\t"  // 255 - phaseL -> phaseL
  "mul %1, %0"              "\n\t"  // multiply first sample by phaseL
  "add r30, r0"             "\n\t"  // accumulate L
  "adc r31, r1"             "\n\t"  // accumulate H
  "eor r1, r1"              "\n\t"  // reset r1 after multiplication
  "mov %0, r31"             "\n\t"  // use sum H as output
  : "=r" (result), "=r" (work)
  : "r" (table), "r" (phase)
  : "r30", "r31"
  );
  return result;
}

static inline uint16_t U8MixU16(uint8_t a, uint8_t b, uint8_t balance) {
  uint16_t result;
  asm(
  "mul %3, %2"      "\n\t"  // b * balance
  "movw %A0, r0"    "\n\t"  // to sum
  "com %2"          "\n\t"  // 255 - balance
  "mul %1, %2"      "\n\t"  // a * (255 - balance)
  "com %2"          "\n\t"  // reset balance to its previous value
  "add %A0, r0"     "\n\t"  // add to sum L
  "adc %B0, r1"     "\n\t"  // add to sum H
  "eor r1, r1"      "\n\t"  // reset r1 after multiplication
  : "&=r" (result)
  : "a" (a), "a" (balance), "a" (b)
  );
  return result;
}


//-------------------------------------------------------------------------
// Attack increments 16Bit
//-------------------------------------------------------------------------
const uint16_t lut_res_env_portamento_increments[] PROGMEM = {
  
  65535,  18904,  16416,  14304,  12504,  10968,   9647,   8509,
  7525,   6672,   5931,   5285,   4719,   4224,   3788,   3405,
  3066,   2766,   2500,   2264,   2053,   1865,   1697,   1546,
  1411,   1290,   1180,   1082,    993,    912,    839,    773,
  713,    658,    608,    562,    521,    483,    448,    416,
  387,    360,    335,    313,    292,    272,    255,    238,
  223,    209,    196,    184,    172,    162,    152,    143,
  135,    127,    119,    113,    106,    100,     95,     90,
  85,     80,     76,     72,     68,     64,     61,     58,
  55,     52,     50,     47,     45,     43,     41,     39,
  37,     35,     33,     32,     30,     29,     28,     26,
  25,     24,     23,     22,     21,     20,     19,     18,
  18,     17,     16,     16,     15,     14,     14,     13,
  13,     12,     12,     11,     11,     10,     10,      9,
  9,      9,      8,      7,      7,      6,      6,      5,
  5,      4,      4,      3,      3,      2,      2,      1  
};

const uint8_t wav_res_env_expo[] PROGMEM = {
  0,      4,      9,     14,     19,     23,     28,     32,
  37,     41,     45,     49,     53,     57,     61,     65,
  68,     72,     76,     79,     83,     86,     89,     92,
  96,     99,    102,    105,    108,    111,    113,    116,
  119,    121,    124,    127,    129,    132,    134,    136,
  139,    141,    143,    145,    148,    150,    152,    154,
  156,    158,    160,    161,    163,    165,    167,    169,
  170,    172,    174,    175,    177,    178,    180,    181,
  183,    184,    186,    187,    188,    190,    191,    192,
  193,    195,    196,    197,    198,    199,    200,    201,
  202,    203,    205,    206,    206,    207,    208,    209,
  210,    211,    212,    213,    214,    215,    215,    216,
  217,    218,    218,    219,    220,    221,    221,    222,
  223,    223,    224,    225,    225,    226,    226,    227,
  227,    228,    229,    229,    230,    230,    231,    231,
  232,    232,    233,    233,    233,    234,    234,    235,
  235,    236,    236,    236,    237,    237,    238,    238,
  238,    239,    239,    239,    240,    240,    240,    241,
  241,    241,    241,    242,    242,    242,    243,    243,
  243,    243,    244,    244,    244,    244,    245,    245,
  245,    245,    245,    246,    246,    246,    246,    246,
  247,    247,    247,    247,    247,    248,    248,    248,
  248,    248,    248,    248,    249,    249,    249,    249,
  249,    249,    249,    250,    250,    250,    250,    250,
  250,    250,    250,    251,    251,    251,    251,    251,
  251,    251,    251,    251,    251,    252,    252,    252,
  252,    252,    252,    252,    252,    252,    252,    252,
  252,    253,    253,    253,    253,    253,    253,    253,
  253,    253,    253,    253,    253,    253,    253,    253,
  253,    254,    254,    254,    254,    254,    254,    254,
  254,    254,    254,    254,    254,    254,    254,    254,
  254,    254,    254,    254,    254,    254,    254,    255,
  255
};

//-------------------------------------------------------------------------
// Sustain level 16Bit
//-------------------------------------------------------------------------
const uint16_t sustain_level[] PROGMEM = {
      1,    11,    33,    65,   106,   157,   218,   287,
      366,   454,   550,   655,   769,   891,  1022,  1162,
      1310,  1466,  1630,  1803,  1984,  2173,  2370,  2576,
      2789,  3011,  3240,  3477,  3723,  3976,  4237,  4506,
      4783,  5068,  5360,  5660,  5968,  6284,  6607,  6938,
      7277,  7623,  7977,  8338,  8707,  9084,  9468,  9860,
      10259, 10666, 11080, 11502, 11931, 12367, 12811, 13263,
      13722, 14188, 14661, 15142, 15630, 16126, 16629, 17139,
      17657, 18181, 18713, 19253, 19799, 20353, 20914, 21483,
      22058, 22641, 23231, 23828, 24432, 25043, 25662, 26288,
      26920, 27560, 28207, 28862, 29523, 30191, 30867, 31549,
      32239, 32935, 33639, 34350, 35068, 35792, 36524, 37263,
      38009, 38762, 39522, 40288, 41062, 41843, 42631, 43425,
      44227, 45036, 45851, 46674, 47503, 48339, 49182, 50033,
      50889, 51753, 52624, 53502, 54386, 55278, 56176, 57081,
      57993, 58912, 59837, 60770, 61709, 62655, 63608, 65535
};
 
Re: AVR Synthesizer "WAVE 1"

moin, rolf. hab mir gestern zufällig ein y-tube video zu deinem projekt angeschaut und war schwer beeindruckt. wollte ich nur mal loswerden.
dicker :supi:
 


Zurück
Oben