Jump to content

clockbox in slave mode


matoz
 Share

Recommended Posts

Hello,

in main.c, at line 228, I've replace

MIOS_LCD_PrintBCD5(mclock_ctr_measures + 1);

by

MIOS_LCD_PrintBCD5((mclock_ctr_measures & 0x0f) + 1);

have fun !

--

Bonjour,

voici ce que j'ai modifié dans le code :

dans main.c, ligne 228, j'ai remplacé

MIOS_LCD_PrintBCD5(mclock_ctr_measures + 1);

par

MIOS_LCD_PrintBCD5((mclock_ctr_measures & 0x0f) + 1);

Amusez-vous bien !

Link to comment
Share on other sites

Hi,

in order to add the slave function on a clockbox for Matoz25, I need to know precisely (my MIDI and musical knowledge are poor) :

- what MIDI command the slave clockbox will received by the "master"

- witch part of the code I've to modify to catch the command

I think to do the following :

- catch the MIDI command

- emulate a "key press" on clock box panel in the code

bye.

--

Bonsoir,

pour ajouter le mode esclave à la clockbox, j'ai besoin de savoir précisément (je n'y connais pas grand chose en MIDI ni en musique) :

- quelle commande MIDI va envoyer le maitre

- quelle partie du code modifier pour intercepter la commande

Je compte m'y prendre comme ça :

- détecter la commande

- simuler l'appui sur la touche correspondante

A+

Link to comment
Share on other sites

Remy, i think there is two midi command to catch:

- start/stop 

- midi synchro (time code)

If you want, come at my home, i will show you the different command with SeqV3 and the automatic slave function....

Maybe we can find this function in SeqV3 source code...

See you soon...  ;)

Link to comment
Share on other sites

en hexadécimal :

F8 : horloge, faut 24 horloges pour faire une noire à la résolution de 24ppqn

FA : start

FB : stop (si je me souviens bien)

FC : pause

Je t'encourage à regarder audiocommander, y a le code mais j'ai pas pris le temps de le décortiquer (et je sais pas bien le C en plus), aussi je t'encourage à trouver comment faire car ça m'intéresse bcp.

Link to comment
Share on other sites

Hi!

sorry, haven't monitored this topic, because I'm not used to the seq and asm applications ;-)

Yes, definitely agree to stryd, just download the sensorizer source from the link above and take a look at ACSyncronizer.h and .c

These classes are an adopted version of TK's clockbox and support an auto master/slave switch.

You may also look at the main.c file for the forwarding and routing of midi messages.

If you have then concrete questions, just ask in this topic -

Best,

Michael

Link to comment
Share on other sites

Hi,

I'm looking at ACSyncronizer.c, main.c from ACSyncronizer and main.c from clockbox v0_0

In main.c of clockbox I found :

/////////////////////////////////////////////////////////////////////////////
//  This function is called by MIOS when a complete MIDI event has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

The function is empty, as the original clockbox should not received MIDI events.

In ACSyncronizer's main.c, the function is feeted with a lot of instructions. I suppose I've had to copy only the instructions needed as said julienvoirin. But I do not find his values (F8, FA, FB and FC)

I've another question : can I put all the code needed to make 'clockbox slave function' in MPROC_NotifyReceivedEvnt or I should use other parts of the code ?

My idea : there is no real slave or master mode for clockbox. Clockbox still function as well, but I just add instructions that allows clockbox to receive MIDI events.

I've another question : Is another DIN5 input connecteur needed for the clockbox to receive MIDI events ? If no, the clockbox need to have an 'adress' in order to be identified by the master device ? What's appends if MIDI events are received by all box on the MIDI net ?

Thanks !

--

Bonsoir,

J'ai consulté le main.c de ACsyncronizer et celui de la clockbox v0_0. La fonction MPROC_NotifyReceivedEvnt dans le main.c de la clockbox est vide (ce qui est logique), et celle de ACsyncronizer est bien rempli.

Puis-je mettre tout le code nécessaire dans MPROC_NotifyReceivedEvnt ? Mon idée est la suivante : il n'y a pas vraiment de mode escalve ou maître; la clockbox continue de fonctionner normalement mais je lui ajoute simplement la faculté d'obéir en plus à des ordres midi.

La clockbox a t elle besoin d'un autre connecteur DIN5 pour recevoir les ordres midi ou suffit il simplement de modifier le programme ? La clockbox a t elle une adresse sur le réseau MIDI, adresse que le maître devrai spécifier ? Sinon comment font les autres 'box' pour ne réagir qu'aux ordres qui les concernent ?

Merci

Link to comment
Share on other sites

Hi,

In main.c of clockbox I found :

void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2)

The function is empty, as the original clockbox should not received MIDI events.

In ACSyncronizer's main.c, the function is feeted with a lot of instructions.

you're looking at the wrong place -

Midi Clock is no event (like a three-byte NOTE_ON or CC), it's a single byte and therefore in this function


void MPROC_NotifyReceivedByte(unsigned char byte) __wparam
{
#if SENSORIZER_INTERFACE_SYNC
// forward byte to Syncronizer
ACSYNC_ReceiveClock(byte);
#endif
}
[/code]

and in ACSyncronizer.c you will find the appropriate handler:

[code=ACSyncronizer]
/////////////////////////////////////////////////////////////////////////////
// This function should be called from MPROC_NotifyReceivedByte
// to update the MIDI clock
/////////////////////////////////////////////////////////////////////////////
void ACSYNC_ReceiveClock(unsigned char byte) __wparam {
switch(byte) {
case MIDI_CLOCK:
if( mclock_state.IS_MASTER ) {
// fall back to slave mode
mclock_state.IS_MASTER = FALSE;
ACSYNC_BPMSet(0); // stops timer (passive call in SLAVE mode)
// request display update
acapp.displayNeedsUpdate = 1;
} else {
// reset lifesign counter (master is alive)
mclock_master_timeout = 0;
// call timer
ACSYNC_Timer(); // passive timer call in SLAVE mode
}
break;
case MIDI_START:
ACSYNC_DoRun();
break;
case MIDI_STOP:
ACSYNC_DoStop();
break;
case MIDI_CONTINUE:
ACSYNC_DoPause();
}
}

it's all there :)

Best,

Michael

Link to comment
Share on other sites

...and btw some details about how it works:

ACSyncronizer starts as MASTER;

if a clock-byte is received, the state is set to SLAVE and the timeout counter is reset;

in the ACSYNC_TICK Loop the timeout counter is incremented;

if the timeout counter exceeds its limit, we know that the clock hasn't been received for a while = automatically fall back to SLAVE:


// if in SLAVE-MODE check if master is still alive
if( mclock_state.IS_MASTER == 0 ) {
++mclock_master_timeout;
// check for timeout
if( mclock_master_timeout > MASTER_IS_ALIVE_COUNTER ) {
mclock_master_timeout = 0;
// fall back to master mode
mclock_state.IS_MASTER = TRUE;
ACSYNC_BPMSet(bpm); // set old bpm value and reInit Timer
// request display update
acapp.displayNeedsUpdate = 1;
}
}
[/code]

pretty simple ;-)

Cheers,

Michael

Link to comment
Share on other sites

  • 2 weeks later...

Hi

I've change clockbox's main.c as follows :

void MPROC_NotifyReceivedByte(unsigned char byte) __wparam
{
// Les Clock ne sont pas des evenenments midi mais de simpes bytes
// d'après le message de julinevoirin :
// 0xF8 : horloge (il en faut 24 pour faire une noire)
// 0xFA : Start
// 0xFB : Stop
// 0xFC : Pause
   if (byte == 0xFA) { //Start
      DIN_NotifyToggle(5,0);
   }
   if (byte == 0xFB) { //Stop
      DIN_NotifyToggle(7,0);
   }
   if (byte == 0xFC) { //Pause
      DIN_NotifyToggle(6,0);
   }
}

But it does not compile :

[tt]D:\_matoz25\clockbox_v0_0>make.bat

...

Compiling main.c

at 1: warning 117: unknown compiler option '--fstack' ignored

main.c:275: warning 112: function 'DIN_NotifyToggle' implicit declaration

main.c:278: warning 112: function 'DIN_NotifyToggle' implicit declaration

main.c:281: warning 112: function 'DIN_NotifyToggle' implicit declaration

main.c:275: error 101: too many parameters

main.c:278: error 101: too many parameters

main.c:281: error 101: too many parameters

ERROR![/tt]

can you help me ?

Thanks

Link to comment
Share on other sites

USER_DIN_NotifyToggle

C_DECLARATION void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value)

DESCRIPTION This function is called by MIOS when an button has been toggled

C_IN Button number in <pin>

Button value <pin_value>:

- 1 if button has been released (=5V)

- 0 if button has been pressed (=0V)

ISR no

http://www.ucapps.de/cmios_fun.html ;)

What are you trying to do there? Rather than fake the button press, you should just call the function directly.

Link to comment
Share on other sites

Problem solved  ;D

you can find the hex file, the source code and an inside view of Matoz's clockbox attached to this message

The clockbox works as a standalone BPM generator; but if it received a Play MIDI Byte from another machine it run as slave, until a Stop MIDI byte is received, then the clockbox return to its normal behavior.

Bye

Source code :

/*
 * Clockbox (MIDI Clock Sender)
 *
 * ==========================================================================
 *
 * Copyright (C) 2005  Thorsten Klose (tk@midibox.org)
 * 
 * ==========================================================================
 * 
 * This file is part of a MIOS application
 *
 * This application is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This application is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with This application; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * ==========================================================================
 */

/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////

#include "cmios.h"
#include "pic18f452.h"

#include "main.h"
#include "mclock.h"
#include "mtc.h"

/////////////////////////////////////////////////////////////////////////////
// Global variables
/////////////////////////////////////////////////////////////////////////////

// status of application (see bitfield declaration in main.h)
app_flags_t app_flags;

/////////////////////////////////////////////////////////////////////////////
// Local variables
/////////////////////////////////////////////////////////////////////////////

//RLUCAS : Mode de la clockbox :
unsigned char sm_mode; // vaut 0 en master, 1 en slave

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after startup to initialize the 
// application
/////////////////////////////////////////////////////////////////////////////
void Init(void) __wparam
{
  //RLUCAS : on démarre en master
  sm_mode=0;

  // set shift register update frequency
  MIOS_SRIO_UpdateFrqSet(1); // ms

  // we need to set at least one IO shift register pair
  MIOS_SRIO_NumberSet(NUMBER_OF_SRIO);

  // debouncing value for DINs
  MIOS_SRIO_DebounceSet(DIN_DEBOUNCE_VALUE);

  // Touch sensor sensitivity *must* be 0, otherwise Port D.4 (CORE::J14) cannot be used as Clock Output
  MIOS_SRIO_TS_SensitivitySet(0);

  // set encoder speed mode of datawheel
  MIOS_ENC_SpeedSet(0, DATAWHEEL_SPEED_MODE, DATAWHEEL_SPEED_DIVIDER);

#if MTC_MODE
  // initialize the MIDI clock module (-> mclock.c)
  MTC_Init();
  MTC_FPSSet(3); // type 3: 30 fps
#else
  // initialize the MIDI clock module (-> mclock.c)
  MCLOCK_Init();
  MCLOCK_BPMSet(140);
#endif
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS in the mainloop when nothing else is to do
/////////////////////////////////////////////////////////////////////////////
void Tick(void) __wparam
{
//RLUCAS :
//if (sm_mode==0) {
#if MTC_MODE
  // this routine sends the MTC code if requested
  MTC_Tick();
#else
  // this routine sends the MIDI clock (and Start/Continue/Stop) if requested
  MCLOCK_Tick();
#endif
//}
}

/////////////////////////////////////////////////////////////////////////////
// This function is periodically called by MIOS. The frequency has to be
// initialized with MIOS_Timer_Set
/////////////////////////////////////////////////////////////////////////////
void Timer(void) __wparam
{
//RLUCAS :
if (sm_mode==0) {
#if MTC_MODE
  // forward timer event to MTC module (-> mtc.c)
  MTC_Timer();
#else
  // forward timer event to MIDI clock module (-> mclock.c)
  MCLOCK_Timer();
#endif
}
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when the display content should be
// initialized. Thats the case during startup and after a temporary message
// has been printed on the screen
/////////////////////////////////////////////////////////////////////////////

// default special character set
// created with http://lcd5x8char.midibox.org
//        ;; char #1
//	db b'00001000', b'00001100'; line 1 / 2
//	db b'00001110', b'00001111'; line 3 / 4
//	db b'00001111', b'00001110'; line 5 / 6
//	db b'00001100', b'00001000'; line 7 / 8
//	;; char #2
//	db b'00000000', b'00000000'; line 1 / 2
//	db b'00001110', b'00001110'; line 3 / 4
//	db b'00001110', b'00001110'; line 5 / 6
//	db b'00000000', b'00000000'; line 7 / 8
//	;; char #3
//	db b'00000000', b'00001010'; line 1 / 2
//	db b'00001010', b'00001010'; line 3 / 4
//	db b'00001010', b'00001010'; line 5 / 6
//	db b'00001010', b'00000000'; line 7 / 8

const unsigned char lcd_charset[3*8] = {
  0x08, 0x0c, 0x0e, 0x0f, 0x0f, 0x0e, 0x0c, 0x08, // Play
  0x00, 0x00, 0x0e, 0x0e, 0x0e, 0x0e, 0x00, 0x00, // Stop
  0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, // Pause
  };

void DISPLAY_Init(void) __wparam
{
  // init default charset
  MIOS_CLCD_SpecialCharsInit(lcd_charset);

  // clear screen
  MIOS_LCD_Clear();

  // print default screen
  MIOS_LCD_CursorSet(0x00); // first line
#if MTC_MODE
  MIOS_LCD_PrintCString("FPS Time");
#else
  MIOS_LCD_PrintCString("BPM  Meter");
#endif

  // request display update
  app_flags.DISPLAY_UPDATE_REQ = 1;
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called in the mainloop when no temporary message is shown
//  on screen. Print the realtime messages here
/////////////////////////////////////////////////////////////////////////////
void DISPLAY_Tick(void) __wparam
{
  unsigned char fps;

  // do nothing if no update has been requested
  if( !app_flags.DISPLAY_UPDATE_REQ )
    return;

  // clear request
  app_flags.DISPLAY_UPDATE_REQ = 0;

  // print Play/Stop/Pause char at the right upper corner
  MIOS_LCD_CursorSet(0x00 + 15);
#if MTC_MODE
  if( mtc_state.PAUSE ) {
    MIOS_LCD_PrintChar(0x02); // Pause
  } else {
    if( mtc_state.RUN ) {
      MIOS_LCD_PrintChar(0x00); // Play
    } else {
      MIOS_LCD_PrintChar(0x01); // Stop
    }
  }

  // print FPS at lower line, left side
  MIOS_LCD_CursorSet(0x40 + 0);
  switch( MTC_FPSGet() ) {
    case 0: fps = 24; break;
    case 1: fps = 25; break;
    case 2: fps = 30; break;
    case 3: fps = 30; break;
    default: fps = 0; break;
  }
  MIOS_LCD_PrintBCD3(fps);

  // print the meter at lower line, right side
  MIOS_LCD_CursorSet(0x40 + 4);
  MIOS_LCD_PrintBCD1(mtc_ctr_hours);
  MIOS_LCD_PrintChar(':');
  MIOS_LCD_PrintBCD2(mtc_ctr_min);
  MIOS_LCD_PrintChar(':');
  MIOS_LCD_PrintBCD2(mtc_ctr_sec);
  MIOS_LCD_PrintChar('.');
  MIOS_LCD_PrintBCD2(mtc_ctr_frame_x_4 / 4);
#else
  if( mclock_state.PAUSE ) {
    MIOS_LCD_PrintChar(0x02); // Pause
  } else {
    if( mclock_state.RUN ) {
      MIOS_LCD_PrintChar(0x00); // Play
    } else {
      MIOS_LCD_PrintChar(0x01); // Stop
    }
  }

  // print BPM at lower line, left side
  MIOS_LCD_CursorSet(0x40 + 0);
  if (sm_mode==1) {
#if MTC_MODE
  MIOS_LCD_PrintCString("SLV");
#else
  MIOS_LCD_PrintCString("SLV");
#endif
  }
  if (sm_mode==0) {
     MIOS_LCD_PrintBCD3(MCLOCK_BPMGet());
  }

  // print the meter at lower line, right side
  MIOS_LCD_CursorSet(0x40 + 4);
// RLUCAS : Modification pour afficher que des measures multiples de 16 :
//  MIOS_LCD_PrintBCD5(mclock_ctr_measures + 1);
  MIOS_LCD_PrintBCD5((mclock_ctr_measures & 0x0f) + 1);
  MIOS_LCD_PrintChar(':');
  MIOS_LCD_PrintChar(' ');
  MIOS_LCD_PrintBCD1(mclock_ctr_beats + 1);
  MIOS_LCD_PrintChar(':');
  MIOS_LCD_PrintBCD3(mclock_ctr_24 * 5);
#endif
}

/////////////////////////////////////////////////////////////////////////////
//  This function is called by MIOS when a complete MIDI event has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has been received
// which has been specified in the MIOS_MPROC_EVENT_TABLE
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI event has not been completly
// received within 2 seconds
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyTimeout(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a MIDI byte has been received
/////////////////////////////////////////////////////////////////////////////
void MPROC_NotifyReceivedByte(unsigned char byte) __wparam
{
// RLUCAS : C'est ici qu'il faut capter les évenements CLOCK MIDI
// Les Clock ne sont pas des evenenments midi mais de simpes bytes
// d'après le message de julinevoirin :
// 0xF8 : horloge (il en faut 24 pour faire une noire)
// 0xFA : Start
// 0xFB : Pause
// 0xFC : Stop
   if (byte == 0xF8) { //horloge
        if (sm_mode==1) {
#if MTC_MODE
            // forward timer event to MTC module (-> mtc.c)
            MTC_Timer();
#else
            // forward timer event to MIDI clock module (-> mclock.c)
            MCLOCK_Timer();
#endif
        }
   }

   if (byte == 0xFA) { //Start
      sm_mode=1;
#if MTC_MODE
 	MTC_DoPlay();
#else
	MCLOCK_DoPlay();
#endif
   }
   if (byte == 0xFB) { //Stop
      sm_mode=0;
#if MTC_MODE
	MTC_DoStop();
#else
        MCLOCK_DoStop();
#endif
   }
   if (byte == 0xFC) { //Pause
      sm_mode=0;
#if MTC_MODE
	MTC_DoStop();
#else
        MCLOCK_DoStop();
#endif
   }
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS before the shift register are loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Prepare(void) __wparam
{
  // this function is called each millisecond
  // we are using it to output the MIDI clock at Pin D.4 for 1 mS
  if( mclock_pin_state.CLK_REQ ) {
    mclock_pin_state.CLK_REQ = 0;
    PORTDbits.RD4 = 1;
  } else {
    PORTDbits.RD4 = 0;
  }
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after the shift register have been loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Finish(void) __wparam
{
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam
{
  // note: pin 0 and 1 are assigned to datawheel (-> see mios_wrapper/mios_tables.inc)
//RLUCAS
if (sm_mode==0) {
  switch( pin ) {
    case 7: // Stop Button
      if( pin_value == 0 )
#if MTC_MODE
	MTC_DoStop();
#else
	MCLOCK_DoStop();
#endif
      break;

    case 6: // Pause Button
      if( pin_value == 0 )
#if MTC_MODE
	MTC_DoPause();
#else
	MCLOCK_DoPause();
#endif
      break;

    case 5: // Play Button
      if( pin_value == 0 )
#if MTC_MODE
	MTC_DoPlay();
#else
	MCLOCK_DoPlay();
#endif
      break;

    case 4: // Rew Button
      if( pin_value == 0 )
#if MTC_MODE
	MTC_DoRew();
#else
	MCLOCK_DoRew();
#endif
      break;

    case 3: // Fwd Button
      if( pin_value == 0 )
#if MTC_MODE
	MTC_DoFwd();
#else
	MCLOCK_DoFwd();
#endif
      break;

    case 8:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(0);
      break;

    case 9:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(0);
      break;

    case 10:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(1);
      break;

    case 11:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(1);
      break;

    case 12:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(2);
      break;

    case 13:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(2);
      break;

    case 14:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(3);
      break;

    case 15:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(3);
      break;

    case 16:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(4);
      break;

    case 17:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(4);
      break;

    case 18:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(5);
      break;

    case 19:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(5);
      break;

    case 20:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(6);
      break;

    case 21:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(6);
      break;

    case 22:
      if( pin_value == 0 )
	MCLOCK_DoMultiStop(7);
      break;

    case 23:
      if( pin_value == 0 )
	MCLOCK_DoMultiPlay(7);
      break;

    default:
#if 0
      // enable this for debugging (displays the number of a non-assigned pin)
      MIOS_LCD_CursorSet(0x00);
      MIOS_LCD_PrintCString("DIN: ");
      MIOS_LCD_PrintBCD3(pin);
      MIOS_LCD_PrintChar(pin_value ? 'o' : '*');
#endif
  }
  }
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam
{
  unsigned int value;
//RLUCAS
if (sm_mode==0) {
  // encoder 0 is used to control the BPM or second (MTC mode)
  if( encoder == 0 ) {
#if MTC_MODE
    if( incrementer < 0 ) {
      while( ++incrementer != 0 )
	MTC_DoRew();
    } else {
      while( --incrementer != 0 )
	MTC_DoFwd();
    }
#else
    value = (unsigned int)MCLOCK_BPMGet() - 48;
    if( MIOS_HLP_16bitAddSaturate(incrementer, &value, 255 - 48) ) {
      MCLOCK_BPMSet((unsigned char)value + 48);
      app_flags.DISPLAY_UPDATE_REQ = 1;
    }
#endif
  }
  }
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam
{
}

project.hex

main.c

2979_Img_4369_jpg4b76764949e0360dd8bc508

Link to comment
Share on other sites

  • 4 years later...

Last year I builded the clockbox V1_5ekx and it's working great. But I would really like to 'slave' the clockbox to my PC.

After a long search I came across this topic and 'electroremy'seems to have solved the issue. So I started experimenting with it.

I downloaded the clockbox_enhanced_v1c.zip from the MIOS download section and changed the main.c code with the new code from 'electroremy'. Then I recompiled the code and uploaded the new project.hex file to my clockbox. Everything seems to work, midi runs and the box automatically 'slaves' to an incoming midi clock. So that's great! BUT the software is not compatible with my v1.5ekx hardware. And I don't know how to solve it.

I tried to change the code from 'electroremy' with the main.c code from the v1.5ekx.zip, but then it will not recompile, giving an error message.

Can anybody help me getting my clockbox V1.5ekx slaving to midiclock, or point me in the right direction?!

PS. The code from electroremy also makes the clockbox count to bar 16 and then jumping back to 1, that I don't want, I like my box to count very far.

Any help appreciated

Cheers,

Roel

Edited by Elektruck
Link to comment
Share on other sites

Double posts are not encouraged, they clutter the forum...

Yeah you're right, but because this is a topic from long ago I'm not sure the people that can help me are still active on this forum. Maybe they get a message that there's a new message in this topic.

And maybe other active people see my message on the forum frontpage.

Link to comment
Share on other sites

OK, first of all I want to make clear that I don't know much about programming. I once got a blinking led on my arduino but that's all. But I managed to recompile some code for several midiboxes. Now I've been struggling for 2 full days with clockbox code and I got somewere, so time for questions.

I want to sync my clockbox_ekx to my PC. I tried the HEX file from 'electroremy' and it seems to work. But then I cannot use the great features of the clockbox_ekx version (from forummember 'modularkomplex').

So I looked at the original clockbox_1.1 code and electroremy's code and tried to see the changes, and integrated the changes to the clockbox_ekx main.c code. It works but the clockbox slaves 4 times slower. So when I play my PC with 480 BPM the clockbox plays 120 BPM. And as a slave I cannot start stop the 8 individual output anymore. So that's no good.

After that I tried to get rid of the BPM divider, so changed a lot of 96 values to 24. Now the clockbox synced in the right BPM! but all features of the ekx version didn't work anymore. No good.

So I started over again and only copied the part about 'recieving midi byte' from the main.c from electroremy into the main.c of the Clockbox_ekx. Now all features are still working, and as a slave the clockbox starts and stops on external midiclock but the tempo is now controlled by both machines, and totally not in sync, of course.

The new pasted code in main.c says to look at mclock.c. I looked but I don't got any idea.

Any help appreciated!

Link to comment
Share on other sites

And I'm getting somewhere! Now I have a fully working clockbox_1.5ekx, and it slaves to midiclock, but again 4 times as slow. So when the clockbox is master everything works as it should. But when it slaves to my PC it plays 4 times as slow, but with all ekx functionallity. So I have a working set up now, I only have to multiply Abletons BPM by 4.

I guess the problem is almost solved but I don't know how to. I tried different things, like turning every 96 to 24, in the mainc and clock.c, but that didn't help, the BMP counter counted 4 times as fast after that, but the tempo played the same. I'll experiment further and every help is still welcome!

Link to comment
Share on other sites

Have you tried to slave it to other software than Ableton? Does it show the same behaviour then? If not, it might be Ableton that is at fault here?

No I didn't, cause I'm quite sure it's part of the clockbox ekx software. But to be sure I just slaved the clockbox to my mb808 drumsequencer and indeed, clockbox still slaves 4 times as slow.

It's not so strange as it seems cause in clockbox 1.5ekx's changelog is something written about that the 24ppgn resolution is changed to a 96ppqn. I guess that's the reason for slaving 4 times slower. Modularkomplex did this resolution changing thing , cause he programmed a BPM divider for all 8 outputs. So you divide the individual outbut by 1,2,3,4 or 6. Great app!

I'll compare the files of clockbox 1.1 and clockbox 1.5ekx to see if I can find this division thing and see what I can do with it.

I'm starting to get really excited about this puzzle. Programming, and code-stuff was always completely abracadabra for me, but after reading the codes over and over and compare it and then some copiing and pasting, I managed to get my box to slave to midiclock, ok 4 times as slow, but I now believe that I can solve this, I'm really proud. (Any help still welcome)

Thanx for your reply!

Link to comment
Share on other sites

Ok as possitive as I was before, as down am I now. I spent another couple of hours on these codes but I can't get my clockbox syning on the right timebase.

I hope some more experienced people want to look at the code. Here are 2 rar files. Both clockbox 1.5ekx with a slave divided by 4 function. One has the 96 ppq resoltution, the other the 24 ppq. They both work the same and react the same to incomming midi clock. Only the song position counter of the 24 ppq counts 4 times as fast as the 96 one. The fast counting song position equals the Master (ableton live's) song position. But still outputs a midiclock divided by 4.

I hope someone can help.

clockbox v1.5ekx w. slave 24.rar

clockbox v1.5ekx w. slave 96.rar

Edited by Elektruck
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...