Jump to content

julienvoirin

Programmer
  • Posts

    790
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by julienvoirin

  1. well, i learned C code by reading the sources of other members on the forum and TK tutorials. I do not know ASM and find it to hard to understand without some courses :/

    that project doesn't require power/ressource as it is rather basic and MIOS is very well conceived. If i use MIOS32, it is because i got a spare STM32 and need 2 midi in/out.

  2. arf, so sad you don't do C. It is so easy to understand, and so portable.

    I will, of course, implement a control surface, based on PG 300 design, with faders (e.g L1 L2 L3 L4), knobs (e.g T1 T2 T3 T4) buttons (e.g OSC waveform) and LEDs :) EDIT : i moved to iPad TouchOSC and a custom Arduino translator to get dynamic patch view

    An original edit buffer will retain the original value and the modified one of each parameter and print it on a LCD Display. I already have that on my Matrix 1000 controller (C Code !)

    A stuff very useful is to send double control messages : control change to the DAW in order to record & edit curves, and sysex to the synth. That's why i coded the translator on the 106. --> EDIT : true and false, MIOS32 is faster than the Juno and CC curves from Logic make hear stepper ladder artifacts :$

  3. Brilliance!

    Combine the above with a control surface and we get Sysex to the MKS-50/JU-1/2 etc plus CCs to anything reasonably modern :flowers:

    This could be full of so much win.

    I quickly started the new application for my Juno 2 : it converts CC to Alpha Juno2 sysex, as i wanted to know if there is scales effect while moving parameters (I got that on my Oberheim Matrix 1000 and it is shit!). There is no scale effect ! :frantics:

    so the next step is to build a dedicated control surface.

    This application does convert Control Change messages to Juno 2 sysex messages

    so that you can control your synth with a DAW that doesn't support

    sysex (e.g Ableton live).

    Connect your Juno to Midi in/out sockets 1 of STM32 and USB to your computer.

    Midi in/out 2 is the same as USB (e.g to connect to an Akai MPC).

    See tables below to edit your Juno parameters (CC84 to CC119).

    Have fun !

    PS : Am I right we all posess Juno 106 AND Juno2 ?!

    /*
    
     *	Roland Juno 2 SysEx Translator
    
     *
    
     *	===============================================================================
    
     *	Copyright (C) 2011 Julien Voirin (julien.voirin@free.fr) *
    
     *  Licensed for personal non-commercial use only.
    
     *  All other rights reserved.
    
     * 
    
     * ==========================================================================
    
     */
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // Include files
    
    /////////////////////////////////////////////////////////////////////////////
    
    
    #include <mios32.h>
    
    #include "app.h"
    
    #include "mios32_config.h"
    
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // Translate a DAW CC string from a Juno 2 SysEx string on a destination port
    
    /////////////////////////////////////////////////////////////////////////////
    
    void Translate_CC_SysEx(mios32_midi_package_t midi_package, mios32_midi_port_t port)
    
    {
    
    	static u8 stream_sysex[10];
    
    
    	// convert CC:USB0 -> Sysex:UART0 : translate CC to SysEx
    
    	if( midi_package.type == 0xb){
    
    		// define sysex stream
    
    		stream_sysex[0] = 0xf0; // header
    
    		stream_sysex[1] = 0x41; // Roland
    
    		stream_sysex[2] = 0x36; // Juno 2 in Individual Tone Parameters mode
    
    		stream_sysex[3] = midi_package.evnt0 & 0x0f; // midi channel : 0n
    
    		stream_sysex[4] = 0x23; // format type 
    
    		stream_sysex[5] = 0x20; // unknown 
    
    		stream_sysex[6] = 0x01; // unknown 
    
    		stream_sysex[7] = midi_package.evnt1 - CC_Offset; // Parameter number
    
    		stream_sysex[8] = midi_package.evnt2; // Parameter value
    
    		stream_sysex[9] = 0xf7; // EOX
    
    
    		// send stream to midi out1
    
    		MIOS32_MIDI_SendSysEx(port, stream_sysex, 10);
    
    		//MIOS32_MIDI_SendSysEx(USB0, stream_sysex, 7); // DEBUG :°)
    
            }
    
    }
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // This hook is called after startup to initialize the application
    
    /////////////////////////////////////////////////////////////////////////////
    
    void APP_Init(void)
    
    {
    
      // initialize all LEDs
    
      MIOS32_BOARD_LED_Init(0xffffffff);
    
    }
    
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // This task is running endless in background
    
    /////////////////////////////////////////////////////////////////////////////
    
    void APP_Background(void)
    
    {
    
    /*
    
      // endless loop
    
      while( 1 ) {
    
        // toggle the state of all LEDs (allows to measure the execution speed with a scope)
    
        MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get());
    
    
      }
    
    */
    
    }
    
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // This hook is called when a MIDI package has been received
    
    /////////////////////////////////////////////////////////////////////////////
    
    void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
    
    {
    
    	// toggle Status LED on each incoming MIDI package
    
    	MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
    
    
    #if TERM_DEBUG  // send received MIDI package to MIOS Terminal
    
    	MIOS32_MIDI_SendDebugMessage("Port:%02X  Type:%X  Evnt0:%02X  Evnt1:%02X  Evnt2:%02X\n", port, midi_package.type, midi_package.evnt0, midi_package.evnt1, midi_package.evnt2);
    
    #endif
    
    
    	// forward USB0->UART0 and UART0->USB0
    
    	switch( port ) {
    
    
    		case USB0:  
    
    			// convert CC:USB0 -> Sysex:UART0 : translate CC to SysEx
    
    			Translate_CC_SysEx(midi_package, UART0);
    
    			MIOS32_MIDI_SendPackage( UART0, midi_package); // forward all messages
    
    			break;
    
    
    		case UART1:  
    
    			// convert CC:UART1 -> Sysex:UART0 : translate CC to SysEx
    
    			Translate_CC_SysEx(midi_package, UART0);
    
    			MIOS32_MIDI_SendPackage( UART0, midi_package); // forward all messages
    
    			break;
    
    
    		case UART0: 
    
    			// translate sysex from Juno to CC : not yet implemented
    
    			//Translate_SysEx_CC( port, midi_package);                                
    
    
    			// passthrough midi messages except SysEx
    
    			if (midi_package.type > 0x7 && midi_package.type < 0xf) // all except SysEx
    
    				MIOS32_MIDI_SendPackage(USB0,  midi_package);   // USB Port
    
    				MIOS32_MIDI_SendPackage(UART1,  midi_package);  // Midi Out2 Port
    
    			break;
    
            }
    
    
    }
    
    
    

    Juno_2_SysEx_Translator_v0.1.zip

  4. Here is my first custom app using the "new" mios32 environment. :thumbsup:

    It only uses a STM 32 board : Juno 106 is connected to Midi in/out 1 and the core32 can be connected to your computer via USB or Midi in/out 2

    The purpose is to convert the sysex from the Juno 106 to Control change messages (CC) (and vice versa), in order to edit automations in DAW that don't support sysex (e.g Ableton Live). Moreover it is really easier to edit CC messages (curves) than sysex ones (list of numbers) !

    It does also convert CC messages received on USB and Midi in/out 2 to juno 106 sysex.



    • In Control mode (meaning just moving the faders of the Juno), it sends simple CC.




      • In Patch mode (e.g recalling patch A45 on the Juno), it sends a program change message and all the data of the controls via 18 CC so that you will ever get the patch parameters ; playing the record will transmit those CC and your Juno will return to its original tone :thumbsup:

      [*]In Manual mode it only sends all 18 parameters when you press the Manual button on the Juno. Moving faders sends sysex as in Control mode.

      Notice that you have to be in Midi Mode III on the Juno. (the only mode that produce sysex)

      Control change messages are the following :

      Control number of control change message

      00 = LFO rate CC 102

      01 = LFO delay time CC 103

      02 = DCO LFO CC 104

      03 = DCO PWM CC 105

      04 = DCO Noise CC 106

      05 = VCF Freq CC 107

      06 = VCF Res etc ...

      07 = VCF Env

      08 = VCF LFO

      09 = VCF Kybd

      0A = VCA Level

      0B = ENV A

      0C = ENV D

      0D = ENV S ...

      0E = ENV R CC 116

      0F = DCO SUB CC 117

      10 = Switches 1 (see below) CC 118

      11 = Switches 2 (see below) CC 119

      You can change it in app.h by editing CC_Offset. The 102 value has been retained because I needed 18 adjacent numbers.

      Enjoy !

      Rq : For those curious of some code routines :

    /*
    
     * Juno 106 SysEx Translator v1.0
    
     *
    
     * ==========================================================================
    
     *
    
     *  Copyright (C) 2011 Julien Voirin (julien.voirin@free.fr)
    
     *  Licensed for personal non-commercial use only.
    
     *  All other rights reserved.
    
     * 
    
     * ==========================================================================
    
     */
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // Include files
    
    /////////////////////////////////////////////////////////////////////////////
    
    
    #include <mios32.h>
    
    #include "app.h"
    
    #include "mios32_config.h"
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // Translate a DAW CC string from a Juno 106 SysEx string on a destination port
    
    /////////////////////////////////////////////////////////////////////////////
    
    void Translate_CC_SysEx(mios32_midi_package_t midi_package, mios32_midi_port_t port)
    
    {
    
    	static u8 stream_sysex[7];
    
    
    	// convert CC:USB0 -> Sysex:UART0 : translate CC to SysEx
    
    	if( midi_package.type == 0xb){
    
    		// define sysex stream
    
    		stream_sysex[0] = 0xf0; // header
    
    		stream_sysex[1] = 0x41; // Roland
    
    		stream_sysex[2] = 0x32; // Juno 106 Control mode
    
    		stream_sysex[3] = midi_package.evnt0 & 0x0f; // midi channel : 0n
    
    		stream_sysex[4] = midi_package.evnt1 - CC_Offset; // Control number
    
    		stream_sysex[5] = midi_package.evnt2; // Control value
    
    		stream_sysex[6] = 0xf7; // EOX
    
    
    		// send stream to midi out1
    
    		MIOS32_MIDI_SendSysEx(port, stream_sysex, 7);
    
    		//MIOS32_MIDI_SendSysEx(USB0, stream_sysex, 7); // DEBUG :°)
    
    	}
    
    }
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // Translate a Juno SysEx string from a midi port to a Control change string
    
    /////////////////////////////////////////////////////////////////////////////
    
    void Translate_SysEx_CC(mios32_midi_port_t port, mios32_midi_package_t midi_package)
    
    {
    
    	static u8 editbufferstatus;
    
    	static u8 midi_channel;
    
    	static u8 cc_param;
    
    	static u8 cc_value;
    
    
    	//	static u8 patch_param[24]; // 24 bytes for a patch
    
    	static u8 bank_patch_number; // for PC
    
    	static u8 patch_value[24]; // Header + midi channel + PgChg + 18 values of controller + EOX 
    
    
    	// convert Sysex:UART0 -> CC:USB0 & CC:UART1
    
    	switch(editbufferstatus){
    
    		unsigned char i; // for the loop
    
    
    		case 0: // Juno 106 Header
    
    			// Control mode
    
    			if( midi_package.type == 0x4 && midi_package.evnt0 == 0xf0 && midi_package.evnt1 == 0x41 && midi_package.evnt2 == 0x32){
    
    
    				#if DEBUG		
    
    				MIOS32_MIDI_SendCC(USB0, 15, 50, 50); 
    
    				#endif
    
    
    				editbufferstatus = 1;
    
    			}
    
    			// Patch mode
    
    			else if( midi_package.type == 0x4 && midi_package.evnt0 == 0xf0 && midi_package.evnt1 == 0x41 && midi_package.evnt2 == 0x30){
    
    				#if DEBUG		
    
    				MIOS32_MIDI_SendCC(USB0, 15, 40, 40); 
    
    				#endif
    
    
    				editbufferstatus = 30;
    
    				//editbufferstatus = 4;
    
    			}
    
    			// Manual mode
    
    			else if( midi_package.type == 0x4 && midi_package.evnt0 == 0xf0 && midi_package.evnt1 == 0x41 && midi_package.evnt2 == 0x31){
    
    
    				#if DEBUG		
    
    				MIOS32_MIDI_SendCC(USB0, 15, 30, 30); 
    
    				#endif
    
    
    				editbufferstatus = 40;
    
    				//editbufferstatus = 4;
    
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 1: // 2nd block (3 bytes) : Control
    
    			if( midi_package.type == 0x4) { 
    
    				midi_channel = midi_package.evnt0; // CC 1st byte
    
    				cc_param = midi_package.evnt1; // CC 2nd byte (+2 avoid pb with bender)
    
    				cc_value = midi_package.evnt2;  // CC 3rd byte
    
    
    				#if DEBUG
    
    				MIOS32_MIDI_SendCC(USB0, 15, 60, 60); // debug OK
    
    				#endif
    
    
    				editbufferstatus = 2;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 2: // EOX Control
    
    			if( midi_package.type == 0x5 && midi_package.evnt0 == 0xF7){
    
    				MIOS32_MIDI_SendCC(USB0, midi_channel, cc_param + CC_Offset, cc_value); // USB Port
    
    				MIOS32_MIDI_SendCC(UART1, midi_channel, cc_param + CC_Offset, cc_value); // Midi Out2 Port
    
    
    				#if DEBUG
    
    				MIOS32_MIDI_SendCC(USB0, 15, 70, 70); // debug OK :)
    
    				#endif	
    
    
    				editbufferstatus = 0;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 30: // blocks patch 0n pp dd
    
    			if(midi_package.type == 0x04){
    
    				patch_value[3] = midi_package.evnt0; // midi channel
    
    				patch_value[4] = midi_package.evnt1; // bank patch number
    
    				patch_value[5] = midi_package.evnt2; // ctrl 01 LFO Rate
    
    
    				// notice that :
    
    				midi_channel = patch_value[3];
    
    				bank_patch_number = patch_value[4];
    
    
    				// send PC over USB et midi out2
    
    				MIOS32_MIDI_SendProgramChange(USB0, midi_channel, bank_patch_number);
    
    				MIOS32_MIDI_SendProgramChange(UART1, midi_channel, bank_patch_number);
    
    
    				// next step
    
    				editbufferstatus = 31;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 31: // blocks patch dd dd dd
    
    			if(midi_package.type == 0x04){
    
    				patch_value[6] = midi_package.evnt0; // ctrl 02 LFO delay time
    
    				patch_value[7] = midi_package.evnt1; // ctrl 03 DCO LFO
    
    				patch_value[8] = midi_package.evnt2; // ctrl 04 DCO PWM
    
    
    				// next step
    
    				editbufferstatus = 32;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 32: // blocks patch dd dd dd
    
    			if(midi_package.type == 0x04){
    
    				patch_value[9] = midi_package.evnt0; // ctrl 05 DCO noise
    
    				patch_value[10] = midi_package.evnt1; // ctrl 06 VCF Freq
    
    				patch_value[11] = midi_package.evnt2; // ctrl 07 VCF Res
    
    
    				// next step
    
    				editbufferstatus = 33;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 33: // blocks patch dd dd dd
    
    			if(midi_package.type == 0x04){
    
    				patch_value[12] = midi_package.evnt0; // ctrl 08 VCF env
    
    				patch_value[13] = midi_package.evnt1; // ctrl 09 VCF LFO
    
    				patch_value[14] = midi_package.evnt2; // ctrl 10 BCF kbd
    
    
    				// next step
    
    				editbufferstatus = 34;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 34: // blocks patch dd dd dd
    
    			if(midi_package.type == 0x04){
    
    				patch_value[15] = midi_package.evnt0; // ctrl 11 VCA Level
    
    				patch_value[16] = midi_package.evnt1; // ctrl 12 Env A
    
    				patch_value[17] = midi_package.evnt2; // ctrl 13 Env D
    
    
    				// next step
    
    				editbufferstatus = 35;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 35: // blocks patch dd dd dd
    
    			if(midi_package.type == 0x04){
    
    				patch_value[18] = midi_package.evnt0; // ctrl 14 Env S
    
    				patch_value[19] = midi_package.evnt1; // ctrl 15 Env R
    
    				patch_value[20] = midi_package.evnt2; // ctrl 16 DCO Sub
    
    
    				// next step
    
    				editbufferstatus = 36;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 36: // blocks patch dd dd F7
    
    			if(midi_package.type == 0x07){
    
    				patch_value[21] = midi_package.evnt0; // ctrl 17 Switches 1
    
    				patch_value[22] = midi_package.evnt1; // ctrl 18 Switches 2
    
    				patch_value[23] = midi_package.evnt2; // ctrl EOX
    
    
    		/*		// send PC over USB et midi out2
    
    				MIOS32_MIDI_SendProgramChange(USB0, midi_channel, bank_patch_number);
    
    				MIOS32_MIDI_SendProgramChange(UART1, midi_channel, bank_patch_number);
    
    		*/		
    
    				// send the patch param via CC
    
    				for(i=5; i < 23; i++){
    
    					MIOS32_MIDI_SendCC(USB0, midi_channel, (i-5)+CC_Offset, patch_value[i]);
    
    					MIOS32_MIDI_SendCC(UART1, midi_channel, (i-5)+CC_Offset, patch_value[i]);
    
    					editbufferstatus = 0;
    
    				}
    
    				// return to start
    
    				editbufferstatus = 0;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;
    
    
    		case 40: // blocks MANUAL 0n pp dd !NO PROGRAM CHANGE!
    
    			if(midi_package.type == 0x04){
    
    				patch_value[3] = midi_package.evnt0; // midi channel
    
    				patch_value[4] = midi_package.evnt1; // bank patch number
    
    				patch_value[5] = midi_package.evnt2; // ctrl 01 LFO Rate
    
    
    				// notice that :
    
    				midi_channel = patch_value[3];
    
    				bank_patch_number = patch_value[4];
    
    
    				// DON'T send PC over USB et midi out2
    
    				//MIOS32_MIDI_SendProgramChange(USB0, midi_channel, bank_patch_number);
    
    				//MIOS32_MIDI_SendProgramChange(UART1, midi_channel, bank_patch_number);
    
    
    				// next step
    
    				editbufferstatus = 31;
    
    			}
    
    			else
    
    				editbufferstatus = 0;
    
    			break;	
    
    
    		case 4 : // end of Blocks
    
    
    			break;
    
    	}
    
    
    }
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // This hook is called after startup to initialize the application
    
    /////////////////////////////////////////////////////////////////////////////
    
    void APP_Init(void)
    
    {
    
      // initialize all LEDs
    
      MIOS32_BOARD_LED_Init(0xffffffff);
    
    }
    
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // This task is running endless in background
    
    /////////////////////////////////////////////////////////////////////////////
    
    void APP_Background(void)
    
    {
    
    /*  // endless loop
    
      while( 1 ) {
    
        // toggle the state of all LEDs (allows to measure the execution speed with a scope)
    
        MIOS32_BOARD_LED_Set(0xffffffff, ~MIOS32_BOARD_LED_Get());
    
    
      }
    
    */
    
    }
    
    
    
    /////////////////////////////////////////////////////////////////////////////
    
    // This hook is called when a MIDI package has been received
    
    /////////////////////////////////////////////////////////////////////////////
    
    void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
    
    {
    
    
    	// toggle Status LED on each incoming MIDI package
    
    	MIOS32_BOARD_LED_Set(1, ~MIOS32_BOARD_LED_Get());
    
    
    #if TERM_DEBUG	// send received MIDI package to MIOS Terminal
    
    	MIOS32_MIDI_SendDebugMessage("Port:%02X  Type:%X  Evnt0:%02X  Evnt1:%02X  Evnt2:%02X\n", port, midi_package.type, midi_package.evnt0, midi_package.evnt1, midi_package.evnt2);
    
    #endif
    
    
    	// forward USB0->UART0 and UART0->USB0
    
    	switch( port ) {
    
    
    		case USB0:  
    
    			// convert CC:USB0 -> Sysex:UART0 : translate CC to SysEx
    
    			Translate_CC_SysEx(midi_package, UART0);
    
    			MIOS32_MIDI_SendPackage( UART0, midi_package); // forward all messages
    
    			break;
    
    
    		case UART1:  
    
    			// convert CC:UART1 -> Sysex:UART0 : translate CC to SysEx
    
    			Translate_CC_SysEx(midi_package, UART0);
    
    			MIOS32_MIDI_SendPackage( UART0, midi_package); // forward all messages
    
    			break;
    
    
    		case UART0: 
    
    			// translate sysex
    
    			Translate_SysEx_CC( port, midi_package);				
    
    
    			// passthrough midi messages except SysEx
    
    			if (midi_package.type > 0x7 && midi_package.type < 0xf) // all except SysEx
    
    				MIOS32_MIDI_SendPackage(USB0,  midi_package);	// USB Port
    
    				MIOS32_MIDI_SendPackage(UART1,  midi_package);	// Midi Out2 Port
    
    			break;
    
    	}
    
    
    }
    
    

    Juno_106_Translator_v1.0.zip

    • Like 1
  5. headphone socket is a add on. Wilba thought to this in order to make a ALL 4 SID in one stereo pair. Somewhere he explains how to cable it (with 10k resistor to attenuate crossrejection signal). If you can find it, i am interested too.

    You hear SID1 (and only this one) in the headphone cause headphone is connected to stereo jack of SID1 (and only this one, that's why there is the 1k parallels resistor trick to create under the PCB)

    If I well understand, the 1k resistors form a passive mixer and there is a trick with the cutting jacks

    http://www.panoramiccomputing.com/TomAnselmo/Computing/12.0Speakers/PassiveMixer.gif

  6. using signal diodes (1n4148) permits use of a matrix, i.e 64 buttons with only 8 outputs (1x74HC595) and 8 inputs (1x74HC165)

    some complexe example here http://midibox.org/forums/forum/43-midibox-blm/

    more simple http://www.midibox.org/forum/index.php/topic,10476.msg79411.html

    the idea is the following :

    A column is ON, the others 7 are OFF. then we scan what Row is ON, corresponding to a button press.

    the do it again with next Column, etc...

  7. Traktor (software i'll be using) sends out a midi output with a certain velocity

    if you are sure of that it is rather easy to code :

    l

    evel  = velocity
    
    
    if level > 64 
    
    then Led0 on
    
     Led1 On 
    
     Led2 On
    
    
    if level >80
    
    then Led0 on
    
     Led1 On 
    
     Led2 On
    
     Led3 On

    etc ..

    search in BLM with RGB Led there is a sort of this code

    if the velocity is under 64, there is only one led

    if 64<velocity<80 there is 2 leds

    is >80 there is 3 led

    i've coded in 8 colors (so 8 leds) velocity scale (0-127)

×
×
  • Create New...