diff -rupN seq24-rev48/src/config.h seq24-rev48 adding win32/src/config.h --- seq24-rev48/src/config.h 1969-12-31 18:00:00.000000000 -0600 +++ seq24-rev48 adding win32/src/config.h 2009-05-20 20:54:39.640625000 -0500 @@ -0,0 +1,45 @@ +/* src/config_win32.h. Generated by configure. */ +/* src/config_win32.h.in. Generated from configure.in by autoheader. */ + +/* Define to enable JACK driver */ +#define JACK_SUPPORT 0 +#undef JACK_SUPPORT + +/* Define to enable LASH support */ +#define LASH_SUPPORT 0 +#undef LASH_SUPPORT + +#define ALSA_SUPPORT 0 +#undef ALSA_SUPPORT + +#define PTHREAD_SUPPORT 1 + +/* Name of package */ +#define PACKAGE "seq24" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.9.0-win32-beta-1" + +/* gnu source */ +#define _GNU_SOURCE 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ diff -rupN seq24-rev48/src/config_win32.h seq24-rev48 adding win32/src/config_win32.h --- seq24-rev48/src/config_win32.h 1969-12-31 18:00:00.000000000 -0600 +++ seq24-rev48 adding win32/src/config_win32.h 2009-05-20 20:54:57.171875000 -0500 @@ -0,0 +1,45 @@ +/* src/config_win32.h. Generated by configure. */ +/* src/config_win32.h.in. Generated from configure.in by autoheader. */ + +/* Define to enable JACK driver */ +#define JACK_SUPPORT 0 +#undef JACK_SUPPORT + +/* Define to enable LASH support */ +#define LASH_SUPPORT 0 +#undef LASH_SUPPORT + +#define ALSA_SUPPORT 0 +#undef ALSA_SUPPORT + +#define PTHREAD_SUPPORT 1 + +/* Name of package */ +#define PACKAGE "seq24" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.9.0-win32-beta-1" + +/* gnu source */ +#define _GNU_SOURCE 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ diff -rupN seq24-rev48/src/event.h seq24-rev48 adding win32/src/event.h --- seq24-rev48/src/event.h 2009-04-14 20:29:26.968750000 -0500 +++ seq24-rev48 adding win32/src/event.h 2009-05-20 20:30:45.984375000 -0500 @@ -34,7 +34,11 @@ const unsigned char EVENT_PROGRAM_CHANG const unsigned char EVENT_CHANNEL_PRESSURE = 0xD0; const unsigned char EVENT_PITCH_WHEEL = 0xE0; const unsigned char EVENT_CLEAR_CHAN_MASK = 0xF0; +const unsigned char EVENT_MIDI_SONG_POS = 0xF2; const unsigned char EVENT_MIDI_CLOCK = 0xF8; +const unsigned char EVENT_MIDI_START = 0xFA; +const unsigned char EVENT_MIDI_STOP = 0xFC; +const unsigned char EVENT_MIDI_CONTINUE = 0xFB; const unsigned char EVENT_SYSEX = 0xF0; const unsigned char EVENT_SYSEX_END = 0xF7; diff -rupN seq24-rev48/src/midibus.cpp seq24-rev48 adding win32/src/midibus.cpp --- seq24-rev48/src/midibus.cpp 2009-04-14 20:29:26.687500000 -0500 +++ seq24-rev48 adding win32/src/midibus.cpp 2009-05-20 20:30:46.343750000 -0500 @@ -19,9 +19,15 @@ //----------------------------------------------------------------------------- #include "midibus.h" #include "config.h" -#include "sys/poll.h" -#include "lash.h" +#ifdef ALSA_SUPPORT +# include "sys/poll.h" +#endif + +#ifdef LASH_SUPPORT +# include "lash.h" +#endif +#ifdef ALSA_SUPPORT midibus::midibus( int a_localclient, int a_destclient, int a_destport, @@ -84,6 +90,25 @@ midibus::midibus( int a_localclient, m_name = tmp; } +#endif + +midibus::midibus( char a_id, int a_queue ) +{ + /* set members */ + m_queue = a_queue; + m_id = a_id; + m_clock_type = e_clock_off; + m_inputing = false; + + /* copy names */ + char tmp[60]; + snprintf( tmp, 59, "[%d] seq24 %d", + m_id, + m_id ); + + m_name = tmp; +} + int midibus::m_clock_mod = 16 * 4; @@ -107,6 +132,7 @@ midibus::unlock( ) bool midibus::init_out( ) { +#ifdef ALSA_SUPPORT /* temp return */ int ret; @@ -133,13 +159,14 @@ bool midibus::init_out( ) printf( "snd_seq_connect_to(%d:%d) error\n", m_dest_addr_client, m_dest_addr_port); return false; } - +#endif return true; } bool midibus::init_out_sub( ) { +#ifdef ALSA_SUPPORT /* temp return */ int ret; @@ -156,7 +183,7 @@ bool midibus::init_out_sub( ) printf( "snd_seq_create_simple_port(write) error\n"); return false; } - +#endif return true; } @@ -164,7 +191,7 @@ bool midibus::init_out_sub( ) bool midibus::init_in( ) { - +#ifdef ALSA_SUPPORT /* temp return */ int ret; @@ -207,13 +234,14 @@ bool midibus::init_in( ) printf( "snd_seq_connect_from(%d:%d) error\n", m_dest_addr_client, m_dest_addr_port); return false; } - +#endif return true; } bool midibus::init_in_sub( ) { +#ifdef ALSA_SUPPORT /* temp return */ int ret; @@ -230,7 +258,7 @@ bool midibus::init_in_sub( ) printf( "snd_seq_create_simple_port(write) error\n"); return false; } - +#endif return true; } @@ -239,7 +267,7 @@ bool midibus::init_in_sub( ) bool midibus::deinit_in( ) { - +#ifdef ALSA_SUPPORT /* temp return */ int ret; @@ -268,7 +296,7 @@ bool midibus::deinit_in( ) printf( "snd_seq_unsubscribe_port(%d:%d) error\n", m_dest_addr_client, m_dest_addr_port); return false; } - +#endif return true; } @@ -305,7 +333,7 @@ midibus::play( event *a_e24, unsigned ch { lock(); - +#ifdef ALSA_SUPPORT snd_seq_event_t ev; @@ -345,6 +373,7 @@ midibus::play( event *a_e24, unsigned ch /* pump it into the queue */ snd_seq_event_output(m_seq, &ev); +#endif unlock(); } @@ -365,7 +394,7 @@ void midibus::sysex( event *a_e24 ) { lock(); - +#ifdef ALSA_SUPPORT snd_seq_event_t ev; /* clear event */ @@ -400,7 +429,7 @@ midibus::sysex( event *a_e24 ) flush(); } - +#endif unlock(); } @@ -410,9 +439,9 @@ void midibus::flush() { lock(); - +#ifdef ALSA_SUPPORT snd_seq_drain_output( m_seq ); - +#endif unlock(); } @@ -420,6 +449,7 @@ midibus::flush() void midibus::init_clock( long a_tick ) { +#ifdef ALSA_SUPPORT if ( m_clock_type == e_clock_pos && a_tick != 0) { continue_from( a_tick ); @@ -444,11 +474,13 @@ midibus::init_clock( long a_tick ) } +#endif } void midibus::continue_from( long a_tick ) { +#ifdef ALSA_SUPPORT /* tell the device that we are going to start at a certain position */ long pp16th = (c_ppqn / 4); @@ -497,6 +529,7 @@ midibus::continue_from( long a_tick ) flush(); snd_seq_event_output(m_seq, &ev); } +#endif } @@ -504,6 +537,7 @@ midibus::continue_from( long a_tick ) void midibus::start() { +#ifdef ALSA_SUPPORT m_lasttick = -1; if ( m_clock_type != e_clock_off ){ @@ -526,6 +560,7 @@ midibus::start() snd_seq_event_output(m_seq, &ev); } +#endif } @@ -574,7 +609,7 @@ midibus::get_input( ) void midibus::stop() { - +#ifdef ALSA_SUPPORT m_lasttick = -1; if ( m_clock_type != e_clock_off ){ @@ -597,6 +632,7 @@ midibus::stop() snd_seq_event_output(m_seq, &ev); } +#endif } @@ -608,7 +644,7 @@ midibus::clock( long a_tick ) { lock(); - +#ifdef ALSA_SUPPORT if ( m_clock_type != e_clock_off ){ bool done = false; @@ -655,7 +691,7 @@ midibus::clock( long a_tick ) /* and send out */ flush(); } - +#endif unlock(); } @@ -706,13 +742,13 @@ void mastermidibus::start() { lock(); - +#ifdef ALSA_SUPPORT /* start timer */ snd_seq_start_queue( m_alsa_seq, m_queue, NULL ); for ( int i=0; i < m_num_out_buses; i++ ) m_buses_out[i]->start(); - +#endif unlock(); } @@ -722,13 +758,13 @@ mastermidibus::start() mastermidibus::continue_from( long a_tick) { lock(); - +#ifdef ALSA_SUPPORT /* start timer */ snd_seq_start_queue( m_alsa_seq, m_queue, NULL ); for ( int i=0; i < m_num_out_buses; i++ ) m_buses_out[i]->continue_from( a_tick ); - +#endif unlock(); } @@ -752,11 +788,13 @@ mastermidibus::stop() m_buses_out[i]->stop(); +#ifdef ALSA_SUPPORT snd_seq_drain_output( m_alsa_seq ); snd_seq_sync_output_queue( m_alsa_seq ); /* start timer */ snd_seq_stop_queue( m_alsa_seq, m_queue, NULL ); +#endif unlock(); } @@ -777,7 +815,7 @@ void mastermidibus::set_ppqn( int a_ppqn ) { lock(); - +#ifdef ALSA_SUPPORT m_ppqn = a_ppqn; /* allocate tempo struct */ @@ -792,7 +830,7 @@ mastermidibus::set_ppqn( int a_ppqn ) /* give tempo struct to the queue */ snd_seq_set_queue_tempo( m_alsa_seq, m_queue, tempo ); - +#endif unlock(); } @@ -801,7 +839,7 @@ void mastermidibus::set_bpm( int a_bpm ) { lock(); - +#ifdef ALSA_SUPPORT m_bpm = a_bpm; /* allocate tempo struct */ @@ -815,7 +853,7 @@ mastermidibus::set_bpm( int a_bpm ) /* give tempo struct to the queue */ snd_seq_set_queue_tempo(m_alsa_seq, m_queue, tempo ); - +#endif unlock(); } @@ -824,9 +862,9 @@ void mastermidibus::flush() { lock(); - +#ifdef ALSA_SUPPORT snd_seq_drain_output( m_alsa_seq ); - +#endif unlock(); } @@ -852,6 +890,7 @@ mastermidibus::mastermidibus() m_init_input[i] = false; } +#ifdef ALSA_SUPPORT /* open the sequencer client */ ret = snd_seq_open(&m_alsa_seq, "default", SND_SEQ_OPEN_DUPLEX, 0); @@ -865,15 +904,18 @@ mastermidibus::mastermidibus() /* set up our clients queue */ m_queue = snd_seq_alloc_queue( m_alsa_seq ); - +#endif +#ifdef LASH_SUPPORT /* notify lash of our client ID so it can restore connections */ lash_driver->set_alsa_client_id(snd_seq_client_id(m_alsa_seq)); +#endif + } void mastermidibus::init( ) { - +#ifdef ALSA_SUPPORT /* client info */ snd_seq_client_info_t *cinfo; /* port info */ @@ -1031,14 +1073,56 @@ mastermidibus::init( ) for ( int i=0; iinit_out_sub(); + m_buses_out_active[i] = true; + m_buses_out_init[i] = true; + } + + m_num_out_buses = num_buses; + + /* only one in */ + m_buses_in[0] = + new midibus( m_num_in_buses, m_queue); + + m_buses_in[0]->init_in_sub(); + m_buses_in_active[0] = true; + m_buses_in_init[0] = true; + m_num_in_buses = 1; + + + set_bpm( c_bpm ); + set_ppqn( c_ppqn ); + + /* midi input */ + /* poll descriptors */ + + set_sequence_input( false, NULL ); + + for ( int i=0; i 0 ); @@ -1244,7 +1331,7 @@ mastermidibus::port_start( int a_client, { lock(); - +#ifdef ALSA_SUPPORT /* client info */ snd_seq_client_info_t *cinfo; @@ -1361,7 +1448,7 @@ mastermidibus::port_start( int a_client, m_poll_descriptors, m_num_poll_descriptors, POLLIN); - +#endif unlock(); } @@ -1369,7 +1456,7 @@ void mastermidibus::port_exit( int a_client, int a_port ) { lock(); - +#ifdef ALSA_SUPPORT for( int i=0; i< m_num_out_buses; i++ ){ if( m_buses_out[i]->get_client() == a_client && @@ -1387,7 +1474,7 @@ mastermidibus::port_exit( int a_client, m_buses_in_active[i] = false; } } - +#endif unlock(); } @@ -1396,7 +1483,7 @@ bool mastermidibus::get_midi_event( event *a_in ) { lock(); - +#ifdef ALSA_SUPPORT snd_seq_event_t *ev; bool sysex = false; @@ -1506,6 +1593,8 @@ mastermidibus::get_midi_event( event *a_ snd_seq_free_event( ev ); snd_midi_event_free( midi_ev ); +#endif + unlock(); return true; diff -rupN seq24-rev48/src/midibus.h seq24-rev48 adding win32/src/midibus.h --- seq24-rev48/src/midibus.h 2009-04-14 20:29:26.906250000 -0500 +++ seq24-rev48 adding win32/src/midibus.h 2009-05-20 20:30:46.375000000 -0500 @@ -18,14 +18,22 @@ // //----------------------------------------------------------------------------- +#include "config.h" +#ifdef __WIN32__ +# include "midibus_portmidi.h" +#else + class midibus; class mastermidibus; #ifndef SEQ24_MIDIBUS #define SEQ24_MIDIBUS -#include -#include +#if ALSA_SUPPORT +# include +# include +#endif + #include "event.h" #include "sequence.h" #include @@ -57,6 +65,7 @@ class midibus static int m_clock_mod; /* sequencer client handle */ +#if ALSA_SUPPORT snd_seq_t *m_seq; /* address of client */ @@ -65,6 +74,7 @@ class midibus int m_local_addr_client; int m_local_addr_port; +#endif /* id of queue */ int m_queue; @@ -87,6 +97,7 @@ class midibus public: +#if ALSA_SUPPORT /* constructor, client#, port#, sequencer, name of client, name of port */ midibus( int a_localclient, @@ -102,7 +113,14 @@ class midibus snd_seq_t *a_seq, int a_id, int a_queue ); - +#endif + +#ifdef __WIN32__ + midibus( char a_id, + int a_queue ); + +#endif + ~midibus(); bool init_out( ); @@ -140,8 +158,10 @@ class midibus friend class mastermidibus; /* address of client */ +#if ALSA_SUPPORT int get_client( void ) { return m_dest_addr_client; }; int get_port( void ) { return m_dest_addr_port; }; +#endif static void set_clock_mod( int a_clock_mod ); static int get_clock_mod( void ); @@ -153,7 +173,9 @@ class mastermidibus private: /* sequencer client handle */ +#if ALSA_SUPPORT snd_seq_t *m_alsa_seq; +#endif int m_num_out_buses; int m_num_in_buses; @@ -200,8 +222,10 @@ class mastermidibus void init(); - + +#if ALSA_SUPPORT snd_seq_t* get_alsa_seq( ) { return m_alsa_seq; }; +#endif int get_num_out_buses(); int get_num_in_buses(); @@ -248,3 +272,4 @@ class mastermidibus }; #endif +#endif diff -rupN seq24-rev48/src/midibus_portmidi.cpp seq24-rev48 adding win32/src/midibus_portmidi.cpp --- seq24-rev48/src/midibus_portmidi.cpp 1969-12-31 18:00:00.000000000 -0600 +++ seq24-rev48 adding win32/src/midibus_portmidi.cpp 2009-05-20 20:30:46.437500000 -0500 @@ -0,0 +1,817 @@ +//---------------------------------------------------------------------------- +// +// This file is part of seq24. +// +// seq24 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. +// +// seq24 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 seq24; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//----------------------------------------------------------------------------- +#include "midibus_portmidi.h" +#include "config.h" + + + + + +midibus::midibus( char a_id, char a_pm_num, const char *a_client_name ) +{ + /* set members */ + m_pm_num = a_pm_num; + m_id = a_id; + m_clock_type = e_clock_off; + m_inputing = false; + + /* copy names */ + char tmp[60]; + snprintf( tmp, 59, "[%d] %s", + m_id, + a_client_name ); + + m_name = tmp; + m_pms = NULL; +} + +int +midibus::poll_for_midi( ) +{ + if ( m_pm_num ) + { + PmError err = Pm_Poll( m_pms); + + if ( err == FALSE ) + { + return 0; + } + if ( err == TRUE ) + { + return 1; + } + + printf( "Pm_Poll: %s\n", Pm_GetErrorText( err )); + } + + return 0; + +} + +int midibus::m_clock_mod = 16 * 4; + +void +midibus::lock( ) +{ + m_mutex.lock(); +} + + +void +midibus::unlock( ) +{ + m_mutex.unlock(); +} + + + + + +bool midibus::init_out( ) +{ + PmError err = Pm_OpenOutput( &m_pms, m_pm_num, NULL, 100, NULL, NULL, 0); + + if ( err != pmNoError ) + { + printf( "Pm_OpenOutput: %s\n", Pm_GetErrorText( err )); + return false; + } + + return true; +} + + + +bool midibus::init_in( ) +{ + PmError err = Pm_OpenInput( &m_pms, m_pm_num, NULL, 100, NULL, NULL); + + if ( err != pmNoError ) + { + printf( "Pm_OpenInput: %s\n", Pm_GetErrorText( err )); + return false; + } + + return true; +} + +int +midibus::get_id( ) +{ + return m_id; +} + + +void +midibus::print() +{ + printf( "%s" , m_name.c_str() ); +} + +string +midibus::get_name() +{ + return m_name; +} + +midibus::~midibus() +{ + if ( m_pms ) + Pm_Close( m_pms ); + m_pms = NULL; +} + + +/* takes an native event, encodes to alsa event, + puts it in the queue */ +void +midibus::play( event *a_e24, unsigned char a_channel ) +{ + lock(); + + PmEvent event; + event.timestamp = 0; + + /* temp for midi data */ + unsigned char buffer[3]; + + /* fill buffer and set midi channel */ + buffer[0] = a_e24->get_status(); + buffer[0] += (a_channel & 0x0F); + a_e24->get_data( &buffer[1], &buffer[2] ); + + event.message = Pm_Message(buffer[0], buffer[1], buffer[2]); + + PmError err = Pm_Write( m_pms, &event, 1 ); + + unlock(); +} + + +inline long +min ( long a, long b ){ + + if ( a < b ) + return a; + return b; + +} + +/* takes an native event, encodes to alsa event, + puts it in the queue */ +void +midibus::sysex( event *a_e24 ) +{ + lock(); + + unlock(); +} + + +// flushes our local queue events out into ALSA +void +midibus::flush() +{ + +} + + +void +midibus::init_clock( long a_tick ) +{ + + if ( m_clock_type == e_clock_pos && a_tick != 0) + { + continue_from( a_tick ); + } + else + if ( m_clock_type == e_clock_mod || a_tick == 0) + { + start(); + + long clock_mod_ticks = (c_ppqn / 4) * m_clock_mod; + long leftover = ( a_tick % clock_mod_ticks ); + long starting_tick = a_tick - leftover; + + /* was there anything left?, then wait for next beat (16th note) to start clocking */ + if ( leftover > 0) + { + starting_tick += clock_mod_ticks; + } + //printf ( "continue_from leftover[%ld] starting_tick[%ld]\n", leftover, starting_tick ); + + m_lasttick = starting_tick - 1; + + } +} + +void +midibus::continue_from( long a_tick ) +{ + + /* tell the device that we are going to start at a certain position */ + long pp16th = (c_ppqn / 4); + + long leftover = ( a_tick % pp16th ); + long beats = ( a_tick / pp16th ); + + long starting_tick = a_tick - leftover; + + /* was there anything left?, then wait for next beat (16th note) to start clocking */ + if ( leftover > 0) + { + starting_tick += pp16th; + } + //printf ( "continue_from leftover[%ld] starting_tick[%ld]\n", leftover, starting_tick ); + + m_lasttick = starting_tick - 1; + + if ( m_clock_type != e_clock_off ) + { + + PmEvent event; + event.timestamp = 0; + event.message = Pm_Message( EVENT_MIDI_CONTINUE, 0,0 ); + Pm_Write( m_pms, &event, 1 ); + event.message = Pm_Message( EVENT_MIDI_SONG_POS, (beats & 0x3F80 >> 7), (beats & 0x7F) ); + Pm_Write( m_pms, &event, 1 ); + } + +} + + +/* gets it a runnin */ +void +midibus::start() +{ + + m_lasttick = -1; + + if ( m_clock_type != e_clock_off ){ + + PmEvent event; + event.timestamp = 0; + event.message = Pm_Message( EVENT_MIDI_START, 0,0 ); + Pm_Write( m_pms, &event, 1 ); + + } +} + + +void +midibus::set_clock( clock_e a_clock_type ) +{ + m_clock_type = a_clock_type; +} + + +clock_e +midibus::get_clock( ) +{ + return m_clock_type; +} + + + + +void +midibus::set_input( bool a_inputing ) +{ + if ( m_inputing != a_inputing ) + { + m_inputing = a_inputing; + } +} + + +bool +midibus::get_input( ) +{ + return m_inputing; +} + + + +void +midibus::stop() +{ + + m_lasttick = -1; + + if ( m_clock_type != e_clock_off ) + { + PmEvent event; + event.timestamp = 0; + event.message = Pm_Message( EVENT_MIDI_STOP, 0,0 ); + Pm_Write( m_pms, &event, 1 ); + + } + +} + + + + +// generates midi clock +void +midibus::clock( long a_tick ) +{ + + lock(); + + if ( m_clock_type != e_clock_off ){ + + bool done = false; + + long uptotick = a_tick; + + if ( m_lasttick >= uptotick ) + done = true; + + while ( !done ){ + + m_lasttick++; + + if ( m_lasttick >= uptotick ) + done = true; + + /* tick time? */ + if ( m_lasttick % ( c_ppqn / 24 ) == 0 ) + { + + PmEvent event; + event.timestamp = 0; + event.message = Pm_Message( EVENT_MIDI_CLOCK, 0,0 ); + Pm_Write( m_pms, &event, 1 ); + + + } + } + } + + unlock(); +} + + + + +void +mastermidibus::lock( ) +{ + // printf( "mastermidibus::lock()\n" ); + m_mutex.lock(); +} + + +void +mastermidibus::unlock( ) +{ + // printf( "mastermidibus::unlock()\n" ); + m_mutex.unlock(); +} + + + +/* gets it a runnin */ +void +mastermidibus::start() +{ + lock(); + + + for ( int i=0; i < m_num_out_buses; i++ ) + m_buses_out[i]->start(); + + unlock(); +} + + +/* gets it a runnin */ + void +mastermidibus::continue_from( long a_tick) +{ + lock(); + + for ( int i=0; i < m_num_out_buses; i++ ) + m_buses_out[i]->continue_from( a_tick ); + + unlock(); +} + +void +mastermidibus::init_clock( long a_tick ) +{ + lock(); + + for ( int i=0; i < m_num_out_buses; i++ ) + m_buses_out[i]->init_clock( a_tick ); + + unlock(); +} + +void +mastermidibus::stop() +{ + lock(); + + for ( int i=0; i < m_num_out_buses; i++ ) + m_buses_out[i]->stop(); + + unlock(); +} + + +// generates midi clock +void +mastermidibus::clock( long a_tick ) +{ + lock(); + + for ( int i=0; i < m_num_out_buses; i++ ) + m_buses_out[i]->clock( a_tick ); + + unlock(); +} + +void +mastermidibus::set_ppqn( int a_ppqn ) +{ + lock(); + + m_ppqn = a_ppqn; + + unlock(); +} + + +void +mastermidibus::set_bpm( int a_bpm ) +{ + lock(); + + m_bpm = a_bpm; + + unlock(); +} + +// flushes our local queue events out into ALSA +void +mastermidibus::flush() +{ + +} + + + +/* fills the array with our buses */ +mastermidibus::mastermidibus() +{ + /* temp return */ + int ret; + + /* set initial number buses */ + m_num_out_buses = 0; + m_num_in_buses = 0; + + for( int i=0; iinterf, dev_info->name, + dev_info->input, dev_info->output ); + + if ( dev_info->output ) + { + m_buses_out[m_num_out_buses] = + new midibus( m_num_out_buses, i, dev_info->name ); + + if ( m_buses_out[m_num_out_buses]->init_out() ) + { + m_buses_out_active[m_num_out_buses] = true; + m_buses_out_init[m_num_out_buses] = true; + + m_num_out_buses++; + } + else + { + delete m_buses_out[m_num_out_buses]; + } + } + + if ( dev_info->input ) + { + m_buses_in[m_num_in_buses] = + new midibus( m_num_in_buses, i, dev_info->name ); + + if ( m_buses_in[m_num_in_buses]->init_in()) + { + + m_buses_in_active[m_num_in_buses] = true; + m_buses_in_init[m_num_in_buses] = true; + + m_num_in_buses++; + } + else + { + delete m_buses_in[m_num_in_buses]; + } + } + } + + + set_bpm( c_bpm ); + set_ppqn( c_ppqn ); + + /* midi input */ + /* poll descriptors */ + + set_sequence_input( false, NULL ); + + for ( int i=0; isysex( a_ev ); + + flush(); + + unlock(); +} + + +void +mastermidibus::play( unsigned char a_bus, event *a_e24, unsigned char a_channel ) +{ + lock(); + if ( m_buses_out_active[a_bus] && a_bus < m_num_out_buses ){ + m_buses_out[a_bus]->play( a_e24, a_channel ); + } + unlock(); +} + + +void +mastermidibus::set_clock( unsigned char a_bus, clock_e a_clock_type ) +{ + lock(); + if ( a_bus < c_maxBuses ){ + m_init_clock[a_bus] = a_clock_type; + } + if ( m_buses_out_active[a_bus] && a_bus < m_num_out_buses ){ + m_buses_out[a_bus]->set_clock( a_clock_type ); + } + unlock(); +} + +clock_e +mastermidibus::get_clock( unsigned char a_bus ) +{ + if ( m_buses_out_active[a_bus] && a_bus < m_num_out_buses ){ + return m_buses_out[a_bus]->get_clock(); + } + return e_clock_off; +} + +void +midibus::set_clock_mod( int a_clock_mod ) +{ + if (a_clock_mod != 0 ) + m_clock_mod = a_clock_mod; +} + +int +midibus::get_clock_mod( void ) +{ + return m_clock_mod; +} + + +void +mastermidibus::set_input( unsigned char a_bus, bool a_inputing ) +{ + lock(); + if ( a_bus < c_maxBuses ){ + m_init_input[a_bus] = a_inputing; + } + + if ( m_buses_in_active[a_bus] && a_bus < m_num_in_buses ){ + m_buses_in[a_bus]->set_input( a_inputing ); + } + unlock(); +} + +bool +mastermidibus::get_input( unsigned char a_bus ) +{ + if ( m_buses_in_active[a_bus] && a_bus < m_num_in_buses ){ + return m_buses_in[a_bus]->get_input(); + } + return false; +} + + +string +mastermidibus::get_midi_out_bus_name( int a_bus ) +{ + if ( m_buses_out_active[a_bus] && a_bus < m_num_out_buses ){ + return m_buses_out[a_bus]->get_name(); + } +} + + +string +mastermidibus::get_midi_in_bus_name( int a_bus ) +{ + if ( m_buses_in_active[a_bus] && a_bus < m_num_in_buses ){ + return m_buses_in[a_bus]->get_name(); + } +} + + +void +mastermidibus::print() +{ + printf( "Available Buses\n"); + for ( int i=0; im_name.c_str() ); + } +} + + +int +mastermidibus::get_num_out_buses() +{ + return m_num_out_buses; +} + + +int +mastermidibus::get_num_in_buses() +{ + return m_num_in_buses; +} + +int +mastermidibus::poll_for_midi( ) +{ + int ret = 0; + + while(1) + { + for ( int i=0; ipoll_for_midi( )) + { + return 1; + } + } + + Sleep(1); + + return 0; + } +} + +bool +mastermidibus::is_more_input( ){ + + lock(); + + int size=0; + + for ( int i=0; ipoll_for_midi( )) + { + size = 1; + } + } + + unlock(); + + return ( size > 0 ); +} + + + + + +bool +mastermidibus::get_midi_event( event *a_in ) +{ + lock(); + + bool ret = false; + PmEvent event; + PmError err; + + for ( int i=0; ipoll_for_midi( )) + { + err = Pm_Read( m_buses_in[i]->m_pms, &event, 1 ); + if ( err < 0 ) + { + printf( "Pm_Read: %s\n", Pm_GetErrorText( err )); + } + + if ( m_buses_in[i]->m_inputing ) + ret = true; + } + } + + if( !ret ){ + unlock(); + return false; + } + + + a_in->set_status( Pm_MessageStatus(event.message)); + a_in->set_size( 3 ); + a_in->set_data( Pm_MessageData1(event.message), Pm_MessageData2(event.message) ); + + // some keyboards send on's with vel 0 for off + if ( a_in->get_status() == EVENT_NOTE_ON && + a_in->get_note_velocity() == 0x00 ){ + a_in->set_status( EVENT_NOTE_OFF ); + } + + unlock(); + + return true; +} + +void +mastermidibus::set_sequence_input( bool a_state, sequence *a_seq ) +{ + lock(); + + m_seq = a_seq; + m_dumping_input = a_state; + + unlock(); +} + diff -rupN seq24-rev48/src/midibus_portmidi.h seq24-rev48 adding win32/src/midibus_portmidi.h --- seq24-rev48/src/midibus_portmidi.h 1969-12-31 18:00:00.000000000 -0600 +++ seq24-rev48 adding win32/src/midibus_portmidi.h 2009-05-20 20:30:46.468750000 -0500 @@ -0,0 +1,226 @@ +//---------------------------------------------------------------------------- +// +// This file is part of seq24. +// +// seq24 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. +// +// seq24 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 seq24; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//----------------------------------------------------------------------------- + +class midibus; +class mastermidibus; + +#ifndef SEQ24_MIDIBUS +#define SEQ24_MIDIBUS + +#include "portmidi.h" + +#include "event.h" +#include "sequence.h" +#include +#include "mutex.h" +#include "globals.h" + +const int c_midibus_output_size = 0x100000; +const int c_midibus_input_size = 0x100000; +const int c_midibus_sysex_chunk = 0x100; + +enum clock_e +{ + e_clock_off, + e_clock_pos, + e_clock_mod + +}; + +class midibus +{ + + private: + + char m_id; + char m_pm_num; + + clock_e m_clock_type; + bool m_inputing; + + static int m_clock_mod; + + /* name of bus */ + string m_name; + + /* last tick */ + long m_lasttick; + + /* locking */ + mutex m_mutex; + + /* mutex */ + void lock(); + void unlock(); + + PortMidiStream* m_pms; + + + public: + + + midibus( char a_id, + char a_pm_num, + const char *a_client_name ); + + + ~midibus(); + + bool init_out( ); + bool init_in( ); + + void print(); + + string get_name(); + int get_id(); + + /* puts an event in the queue */ + void play( event *a_e24, unsigned char a_channel ); + void sysex( event *a_e24 ); + + int poll_for_midi( ); + + /* clock */ + void start(); + void stop(); + void clock( long a_tick ); + void continue_from( long a_tick ); + void init_clock( long a_tick ); + void set_clock( clock_e a_clocking ); + clock_e get_clock( ); + + void set_input( bool a_inputing ); + bool get_input( ); + + void flush(); + //void remove_queued_on_events( int a_tag ); + + /* master midi bus sets up the bus */ + friend class mastermidibus; + + /* address of client */ +#if ALSA_SUPPORT + int get_client( void ) { return m_dest_addr_client; }; + int get_port( void ) { return m_dest_addr_port; }; +#endif + + static void set_clock_mod( int a_clock_mod ); + static int get_clock_mod( void ); + +}; + +class mastermidibus +{ + private: + + /* sequencer client handle */ +#if ALSA_SUPPORT + snd_seq_t *m_alsa_seq; +#endif + + int m_num_out_buses; + int m_num_in_buses; + + midibus *m_buses_out[c_maxBuses]; + midibus *m_buses_in[c_maxBuses]; + midibus *m_bus_announce; + + bool m_buses_out_active[c_maxBuses]; + bool m_buses_in_active[c_maxBuses]; + + bool m_buses_out_init[c_maxBuses]; + bool m_buses_in_init[c_maxBuses]; + + clock_e m_init_clock[c_maxBuses]; + bool m_init_input[c_maxBuses]; + + /* id of queue */ + int m_queue; + + int m_ppqn; + int m_bpm; + + int m_num_poll_descriptors; + struct pollfd *m_poll_descriptors; + + /* for dumping midi input to sequence for recording */ + bool m_dumping_input; + sequence *m_seq; + + /* locking */ + mutex m_mutex; + + /* mutex */ + void lock(); + void unlock(); + + public: + + mastermidibus(); + ~mastermidibus(); + //midibus *get_default_bus(); + //midibus *get_bus( int a_bus ); + + + void init(); + + int get_num_out_buses(); + int get_num_in_buses(); + + void set_bpm(int a_bpm); + void set_ppqn(int a_ppqn); + int get_bpm(){ return m_bpm;} + int get_ppqn(){ return m_ppqn;} + + string get_midi_out_bus_name( int a_bus ); + string get_midi_in_bus_name( int a_bus ); + + void print(); + void flush(); + + void start(); + void stop(); + + void clock( long a_tick ); + void continue_from( long a_tick ); + void init_clock( long a_tick ); + + int poll_for_midi( ); + bool is_more_input( ); + bool get_midi_event( event *a_in ); + void set_sequence_input( bool a_state, sequence *a_seq ); + + bool is_dumping( ) { return m_dumping_input; } + sequence* get_sequence( ) { return m_seq; } + void sysex( event *a_event ); + + + void play( unsigned char a_bus, event *a_e24, unsigned char a_channel ); + + void set_clock( unsigned char a_bus, clock_e a_clock_type ); + clock_e get_clock( unsigned char a_bus ); + + + void set_input( unsigned char a_bus, bool a_inputing ); + bool get_input( unsigned char a_bus ); + +}; + +#endif diff -rupN seq24-rev48/src/mutex.h seq24-rev48 adding win32/src/mutex.h --- seq24-rev48/src/mutex.h 2009-04-14 20:29:26.578125000 -0500 +++ seq24-rev48 adding win32/src/mutex.h 2009-05-20 20:30:46.625000000 -0500 @@ -19,13 +19,16 @@ //----------------------------------------------------------------------------- #include "globals.h" #include "config.h" +#if PTHREAD_SUPPORT #include +#endif #ifndef SEQ24_MUTEX #define SEQ24_MUTEX class mutex { +#ifdef PTHREAD_SUPPORT private: static const pthread_mutex_t recmutex; @@ -35,6 +38,8 @@ protected: /* mutex lock */ pthread_mutex_t m_mutex_lock; + +#endif public: mutex(); @@ -46,12 +51,13 @@ public: class condition_var : public mutex { +#ifdef PTHREAD_SUPPORT private: static const pthread_cond_t cond; pthread_cond_t m_cond; - +#endif public: condition_var(); diff -rupN seq24-rev48/src/options.cpp seq24-rev48 adding win32/src/options.cpp --- seq24-rev48/src/options.cpp 2009-04-14 20:29:26.968750000 -0500 +++ seq24-rev48 adding win32/src/options.cpp 2009-05-20 20:30:46.656250000 -0500 @@ -141,8 +141,9 @@ options::options (Gtk::Window & parent, vbox->pack_start (*check, false, false); } - - // Jack + +#ifdef JACK_SUPPORT + // Jack options menu VBox *vbox2 = manage (new VBox ()); vbox2->set_border_width (4); m_notebook->pages().push_back(Notebook_Helpers::TabElem(*vbox2, @@ -207,7 +208,6 @@ options::options (Gtk::Window & parent, vbox2->pack_start (*rb_live, false, false); vbox2->pack_start (*rb_perform, false, false); - Gtk::Button * button = manage (new Button ("Connect")); tooltips->set_tip (*button, "Connect to Jack."); button->signal_clicked().connect(bind(mem_fun(*this, @@ -219,7 +219,7 @@ options::options (Gtk::Window & parent, button->signal_clicked().connect(bind(mem_fun(*this, &options::transport_callback), e_jack_disconnect, button)); vbox2->pack_start (*button, false, false); - +#endif /* show everything */ show_all_children (); diff -rupN seq24-rev48/src/perform.cpp seq24-rev48 adding win32/src/perform.cpp --- seq24-rev48/src/perform.cpp 2009-04-14 20:29:27.078125000 -0500 +++ seq24-rev48 adding win32/src/perform.cpp 2009-05-20 20:30:46.937500000 -0500 @@ -21,7 +21,9 @@ #include "midibus.h" #include "event.h" #include -#include +#ifndef __WIN32__ +# include +#endif #include //For keys @@ -1002,15 +1004,24 @@ output_thread_func(void *a_pef ) memset(schp, 0, sizeof(sched_param)); schp->sched_priority = 1; - + +#ifndef __WIN32__ +// Not in MinGW RCB if (sched_setscheduler(0, SCHED_FIFO, schp) != 0) { printf("output_thread_func: couldnt sched_setscheduler(FIFO), you need to be root.\n"); pthread_exit(0); } +#endif } - + +#ifdef __WIN32__ + timeBeginPeriod(1); +#endif p->output_func(); +#ifdef __WIN32__ + timeEndPeriod(1); +#endif return 0; } @@ -1110,6 +1121,7 @@ perform::output_func(void) +#ifndef __WIN32__ /* begning time */ struct timespec last; /* current time */ @@ -1121,6 +1133,19 @@ perform::output_func(void) /* difference between last and current */ struct timespec delta; +#else + /* begning time */ + long last; + /* current time */ + long current; + + long stats_loop_start; + long stats_loop_finish; + + + /* difference between last and current */ + long delta; +#endif /* tick and tick fraction */ double current_tick = 0.0; @@ -1164,13 +1189,20 @@ perform::output_func(void) } - int ppqn = m_master_bus.get_ppqn(); + int ppqn = m_master_bus.get_ppqn(); +#ifndef __WIN32__ /* get start time position */ clock_gettime(CLOCK_REALTIME, &last); if ( global_stats ) stats_last_clock_us= (last.tv_sec * 1000000) + (last.tv_nsec / 1000); +#else + /* get start time position */ + last = timeGetTime(); + if ( global_stats ) + stats_last_clock_us= last * 1000; +#endif @@ -1187,15 +1219,27 @@ perform::output_func(void) **************************************/ if ( global_stats ){ +#ifndef __WIN32__ clock_gettime(CLOCK_REALTIME, &stats_loop_start); +#else + stats_loop_start = timeGetTime(); +#endif } /* delta time */ +#ifndef __WIN32__ clock_gettime(CLOCK_REALTIME, ¤t); delta.tv_sec = (current.tv_sec - last.tv_sec ); delta.tv_nsec = (current.tv_nsec - last.tv_nsec ); long delta_us = (delta.tv_sec * 1000000) + (delta.tv_nsec / 1000); +#else + current = timeGetTime(); + //printf( "current [0x%x]\n", current ); + delta = current - last; + long delta_us = delta * 1000; + //printf( " delta [0x%x]\n", delta ); +#endif /* delta time to ticks */ @@ -1206,6 +1250,7 @@ perform::output_func(void) double delta_tick = (double) (bpm * ppqn * (delta_us/60000000.0f) ); //printf ( "delta_tick[%ld.%03ld]\n", delta_tick, delta_tick_f ); + //printf ( " delta_tick[%lf]\n", delta_tick ); #ifdef JACK_SUPPORT // no init until we get a good lock @@ -1223,7 +1268,7 @@ perform::output_func(void) m_jack_frame_last = m_jack_frame_current; - printf ("[Start Playback]\n" ); + //printf ("[Start Playback]\n" ); dumping = true; m_jack_tick = m_jack_pos.frame * @@ -1401,7 +1446,11 @@ perform::output_func(void) /* was there a tick ? */ if ( stats_total_tick % (c_ppqn / 24) == 0 ){ +#ifndef __WIN32__ long current_us = (current.tv_sec * 1000000) + (current.tv_nsec / 1000); +#else + long current_us = current * 1000; +#endif stats_clock_width_us = current_us - stats_last_clock_us; stats_last_clock_us = current_us; @@ -1425,11 +1474,18 @@ perform::output_func(void) /* set last */ last = current; +#ifndef __WIN32__ clock_gettime(CLOCK_REALTIME, ¤t); delta.tv_sec = (current.tv_sec - last.tv_sec ); delta.tv_nsec = (current.tv_nsec - last.tv_nsec ); long elapsed_us = (delta.tv_sec * 1000000) + (delta.tv_nsec / 1000); //printf( "elapsed_us[%ld]\n", elapsed_us ); +#else + current = timeGetTime(); + delta = current - last; + long elapsed_us = delta * 1000; + //printf( " elapsed_us[%ld]\n", elapsed_us ); +#endif /* now, we want to trigger every c_thread_trigger_width_ms, and it took us delta_us to play() */ @@ -1450,7 +1506,7 @@ perform::output_func(void) delta_us = (long)next_clock_delta_us; } - +#ifndef __WIN32__ if ( delta_us > 0.0 ){ delta.tv_sec = (delta_us / 1000000); @@ -1459,7 +1515,17 @@ perform::output_func(void) //printf("sleeping() "); nanosleep( &delta, NULL ); + } +#else + if ( delta_us > 0 ){ + + delta = (delta_us / 1000); + + //printf(" sleeping() [0x%x]\n", delta); + Sleep(delta); + } +#endif else { @@ -1467,15 +1533,24 @@ perform::output_func(void) printf ("underrun\n" ); } - if ( global_stats ){ + if ( global_stats ){ +#ifndef __WIN32__ clock_gettime(CLOCK_REALTIME, &stats_loop_finish); +#else + stats_loop_finish = timeGetTime(); +#endif } if ( global_stats ){ +#ifndef __WIN32__ delta.tv_sec = (stats_loop_finish.tv_sec - stats_loop_start.tv_sec ); delta.tv_nsec = (stats_loop_finish.tv_nsec - stats_loop_start.tv_nsec ); long delta_us = (delta.tv_sec * 1000000) + (delta.tv_nsec / 1000); +#else + delta = stats_loop_finish - stats_loop_start; + long delta_us = delta * 1000; +#endif int index = delta_us / 100; if ( index >= 100 ) index = 99; @@ -1560,16 +1635,25 @@ input_thread_func(void *a_pef ) memset(schp, 0, sizeof(sched_param)); schp->sched_priority = 1; - + +#ifndef __WIN32__ +// MinGW RCB if (sched_setscheduler(0, SCHED_FIFO, schp) != 0) { printf("input_thread_func: couldnt sched_setscheduler(FIFO), you need to be root.\n"); pthread_exit(0); } +#endif } - - +#ifdef __WIN32__ + timeBeginPeriod(1); +#endif + p->input_func(); + +#ifdef __WIN32__ + timeEndPeriod(1); +#endif return 0; } diff -rupN seq24-rev48/src/perform.h seq24-rev48 adding win32/src/perform.h --- seq24-rev48/src/perform.h 2009-04-14 20:29:26.671875000 -0500 +++ seq24-rev48 adding win32/src/perform.h 2009-05-20 20:30:46.968750000 -0500 @@ -28,7 +28,9 @@ class perform; #include "midibus.h" #include "midifile.h" #include "sequence.h" -#include +#ifndef __WIN32__ +# include +#endif #include diff -rupN seq24-rev48/src/seq24.cpp seq24-rev48 adding win32/src/seq24.cpp --- seq24-rev48/src/seq24.cpp 2009-04-14 20:29:26.656250000 -0500 +++ seq24-rev48 adding win32/src/seq24.cpp 2009-05-20 20:30:47.125000000 -0500 @@ -24,12 +24,19 @@ #include "config.h" #include "font.h" -#include "lash.h" +#ifdef LASH_SUPPORT +# include "lash.h" +#endif +#include "perform.h" #include "mainwnd.h" #include "midifile.h" #include "optionsfile.h" #include "perform.h" #include "userfile.h" +#include "font.h" +#ifdef LASH_SUPPORT +# include "lash.h" +#endif /* struct for command parsing */ static struct @@ -74,7 +81,18 @@ user_midi_bus_definition global_user_m user_instrument_definition global_user_instrument_definitions[c_max_instruments]; font *p_font_renderer; + +#ifdef LASH_SUPPORT lash *lash_driver = NULL; +#endif + +#ifdef __WIN32__ +# define HOME "HOMEPATH" +# define SLASH "\\" +#else +# define HOME "HOME" +# define SLASH "/" +#endif int @@ -92,8 +110,10 @@ main (int argc, char *argv[]) global_user_instrument_definitions[i].controllers_active[j] = false; } - /* init the lash driver (strips lash specific cmdline arguments */ - lash_driver = new lash(&argc, &argv); + /* init the lash driver (strips lash specific cmdline arguments */ +#ifdef LASH_SUPPORT + lash_driver = new lash(&argc, &argv); +#endif /* the main performance object */ perform p; @@ -105,11 +125,11 @@ main (int argc, char *argv[]) p_font_renderer = new font(); - if ( getenv( "HOME" ) != NULL ){ + if ( getenv( HOME ) != NULL ){ - Glib::ustring home( getenv( "HOME" )); + Glib::ustring home( getenv( HOME )); last_used_dir = home; - Glib::ustring total_file = home + "/" + config_filename; + Glib::ustring total_file = home + SLASH + config_filename; printf( "Reading [%s]\n", total_file.c_str()); optionsfile options( total_file ); @@ -118,7 +138,7 @@ main (int argc, char *argv[]) printf( "Error Reading [%s]\n", total_file.c_str()); } - total_file = home + "/" + user_filename; + total_file = home + SLASH + user_filename; printf( "Reading [%s]\n", total_file.c_str()); userfile user( total_file ); @@ -129,14 +149,14 @@ main (int argc, char *argv[]) } else { - printf( "Error calling getenv( \"HOME\" )\n" ); + printf( "Error calling getenv( \"%s\" )\n", HOME ); } /* parse parameters */ int c; - + while (1){ @@ -252,15 +272,17 @@ main (int argc, char *argv[]) mainwnd seq24_window( &p ); - lash_driver->start( &p ); +#ifdef LASH_SUPPORT + lash_driver->start( &p ); +#endif kit.run(seq24_window); p.deinit_jack(); - if ( getenv( "HOME" ) != NULL ){ + if ( getenv( HOME ) != NULL ){ - string home( getenv( "HOME" )); - Glib::ustring total_file = home + "/" + config_filename; + string home( getenv( HOME )); + Glib::ustring total_file = home + SLASH + config_filename; printf( "Writing [%s]\n", total_file.c_str()); optionsfile options( total_file ); @@ -271,10 +293,12 @@ main (int argc, char *argv[]) } else { - printf( "Error calling getenv( \"HOME\" )\n" ); + printf( "Error calling getenv( \"%s\" )\n", HOME ); } - delete lash_driver; +#ifdef LASH_SUPPORT + delete lash_driver; +#endif return 0; } diff -rupN seq24-rev48/src/seqedit.cpp seq24-rev48 adding win32/src/seqedit.cpp --- seq24-rev48/src/seqedit.cpp 2009-04-14 20:29:26.968750000 -0500 +++ seq24-rev48 adding win32/src/seqedit.cpp 2009-05-20 20:30:47.265625000 -0500 @@ -274,6 +274,7 @@ seqedit::seqedit( sequence *a_seq, /* sets scroll bar to the middle */ //gfloat middle = m_vscroll->get_adjustment()->get_upper() / 3; //m_vscroll->get_adjustment()->set_value(middle); + m_seqroll_wid->set_ignore_redraw(true); set_zoom( m_zoom ); set_snap( m_snap ); @@ -291,8 +292,8 @@ seqedit::seqedit( sequence *a_seq, set_scale( m_scale ); set_key( m_key ); - set_key( m_key ); + m_seqroll_wid->set_ignore_redraw(false); add_events(Gdk::SCROLL_MASK); } @@ -1486,7 +1487,7 @@ seqedit::timeout( void ) if (m_seq->is_dirty_edit() ){ - m_seqroll_wid->redraw(); + m_seqroll_wid->redraw_events(); m_seqevent_wid->redraw(); m_seqdata_wid->redraw(); } diff -rupN seq24-rev48/src/seqroll.cpp seq24-rev48 adding win32/src/seqroll.cpp --- seq24-rev48/src/seqroll.cpp 2009-04-14 20:29:27.015625000 -0500 +++ seq24-rev48 adding win32/src/seqroll.cpp 2009-05-20 20:30:47.578125000 -0500 @@ -99,6 +99,8 @@ seqroll::seqroll(perform *a_perf, m_drawing_background_seq = false; set_double_buffered( false ); + + m_ignore_redraw = false; } @@ -108,6 +110,11 @@ seqroll::set_background_sequence( bool a m_drawing_background_seq = a_state; m_background_sequence = a_seq; + if ( m_ignore_redraw ) + return; + +////printf( "set_background_sequence()\n" ); + update_background(); update_pixmap(); queue_draw(); } @@ -179,9 +186,9 @@ seqroll::update_sizes() m_hadjust->set_step_increment( (c_ppqn / 4) * m_zoom); /* The page increment is always one bar */ - int page_increment = c_ppqn * - m_seq->get_bpm() * - (4.0 / m_seq->get_bw()); + int page_increment = int( double(c_ppqn) * + double(m_seq->get_bpm()) * + (4.0 / double(m_seq->get_bw())) ); m_hadjust->set_page_increment(page_increment); @@ -212,6 +219,11 @@ seqroll::update_sizes() m_window_x, m_window_y, -1); + m_background = Gdk::Pixmap::create( m_window, + m_window_x, + m_window_y, + -1); + change_vert(); } } @@ -223,6 +235,11 @@ seqroll::change_horz( ) m_scroll_offset_ticks = (int) m_hadjust->get_value(); m_scroll_offset_x = m_scroll_offset_ticks / m_zoom; + + if ( m_ignore_redraw ) + return; + + update_background(); update_pixmap(); force_draw(); } @@ -233,6 +250,10 @@ seqroll::change_vert( ) m_scroll_offset_key = (int) m_vadjust->get_value(); m_scroll_offset_y = m_scroll_offset_key * c_key_y; + if ( m_ignore_redraw ) + return; + + update_background(); update_pixmap(); force_draw(); @@ -245,7 +266,13 @@ seqroll::reset() m_scroll_offset_ticks = (int) m_hadjust->get_value(); m_scroll_offset_x = m_scroll_offset_ticks / m_zoom; + if ( m_ignore_redraw ) + return; + + //printf( "reset()\n"); + update_sizes(); + update_background(); update_pixmap(); queue_draw(); } @@ -253,24 +280,63 @@ seqroll::reset() void seqroll::redraw() { + if ( m_ignore_redraw ) + return; + m_scroll_offset_ticks = (int) m_hadjust->get_value(); m_scroll_offset_x = m_scroll_offset_ticks / m_zoom; + //printf( "redraw()\n" ); + + update_background(); update_pixmap(); - queue_draw(); + force_draw(); + } -/* updates background */ void -seqroll::draw_background() +seqroll::redraw_events() { + if ( m_ignore_redraw ) + return; + + //printf( "redraw_events()\n" ); + + update_pixmap(); + force_draw(); +} + +void +seqroll::set_ignore_redraw(bool a_ignore) +{ + m_ignore_redraw = a_ignore; +} + +void +seqroll::draw_background_on_pixmap() +{ + m_pixmap->draw_drawable(m_gc, + m_background, + 0, + 0, + 0, + 0, + m_window_x, + m_window_y ); +} - //printf ("draw_background()\n" ); +/* updates background */ +void +seqroll::update_background() +{ + //static int times = 0; + //times++; + //printf ("update_background() %d\n", times ); /* clear background */ m_gc->set_foreground(m_white); - m_pixmap->draw_rectangle(m_gc,true, + m_background->draw_rectangle(m_gc,true, 0, 0, m_window_x, @@ -287,7 +353,7 @@ seqroll::draw_background() for ( int i=0; i< (m_window_y / c_key_y) + 1; i++ ) { - m_pixmap->draw_line(m_gc, + m_background->draw_line(m_gc, 0, i * c_key_y, m_window_x, @@ -299,7 +365,7 @@ seqroll::draw_background() - m_scroll_offset_key - 1 + ( 12 - m_key )) % 12] ) - m_pixmap->draw_rectangle(m_gc,true, + m_background->draw_rectangle(m_gc,true, 0, i * c_key_y + 1, m_window_x, @@ -318,7 +384,7 @@ seqroll::draw_background() //if ( measures_per_line <= 0 int measures_per_line = 1; - //printf( "measures_per_line[%d]\n", measures_per_line ); + ////printf( "measures_per_line[%d]\n", measures_per_line ); int ticks_per_measure = m_seq->get_bpm() * (4 * c_ppqn) / m_seq->get_bw(); int ticks_per_beat = (4 * c_ppqn) / m_seq->get_bw(); @@ -376,7 +442,7 @@ seqroll::draw_background() m_gc->set_dashes( 0, &dash, 1 ); } - m_pixmap->draw_line(m_gc, + m_background->draw_line(m_gc, base_line - m_scroll_offset_x, 0, base_line - m_scroll_offset_x, @@ -443,7 +509,8 @@ seqroll::set_key( int a_key ) void seqroll::update_pixmap() { - draw_background(); + //printf( "update_pixmap()\n" ); + draw_background_on_pixmap(); draw_events_on_pixmap(); } @@ -544,7 +611,7 @@ void seqroll::draw_events_on( Glib::RefP if ( note_width < 1 ) note_width = 1; } else { note_width = (m_seq->get_length() - tick_s) / m_zoom; - } + } } else { note_width = 16 / m_zoom; @@ -628,6 +695,8 @@ seqroll::draw_events_on_pixmap() int seqroll::idle_redraw() { + //printf( "idle_redraw()\n" ); + draw_events_on( m_window ); draw_events_on( m_pixmap ); @@ -758,6 +827,10 @@ seqroll::on_expose_event(GdkEventExpose* void seqroll::force_draw(void ) { + //static int times = 0; + //times++; + //printf ("force_draw() %d\n", times ); + m_window->draw_drawable(m_gc, m_pixmap, 0, @@ -1038,8 +1111,10 @@ seqroll::on_button_press_event(GdkEventB /* if they clicked, something changed */ if ( needs_update ){ - redraw(); + + ////printf( "needs update\n" ); m_seq->set_dirty(); + //redraw_events(); } return true; @@ -1148,8 +1223,9 @@ seqroll::on_button_release_event(GdkEven /* if they clicked, something changed */ if ( needs_update ){ - redraw(); + ////printf( "needs_update2\n" ); m_seq->set_dirty(); + //redraw_events(); } return true; } @@ -1192,6 +1268,7 @@ seqroll::on_motion_notify_event(GdkEvent convert_xy( m_current_x, m_current_y, &tick, ¬e ); m_seq->add_note( tick, m_note_length - 2, note, true ); + return true; } return false; @@ -1320,8 +1397,8 @@ seqroll::on_key_press_event(GdkEventKey* } if ( ret == true ){ - redraw(); m_seq->set_dirty(); + //redraw_events(); return true; } diff -rupN seq24-rev48/src/seqroll.h seq24-rev48 adding win32/src/seqroll.h --- seq24-rev48/src/seqroll.h 2009-04-14 20:29:26.625000000 -0500 +++ seq24-rev48 adding win32/src/seqroll.h 2009-05-20 20:30:47.609375000 -0500 @@ -65,6 +65,7 @@ class seqroll : public Gtk::DrawingArea Gdk::Color m_black, m_white, m_grey, m_dk_grey, m_red; Glib::RefPtr m_pixmap; + Glib::RefPtr m_background; rect m_old; rect m_selected; @@ -125,6 +126,7 @@ class seqroll : public Gtk::DrawingArea int m_background_sequence; bool m_drawing_background_seq; + bool m_ignore_redraw; void on_realize(); bool on_expose_event(GdkEventExpose* a_ev); @@ -174,15 +176,18 @@ class seqroll : public Gtk::DrawingArea void reset(); void redraw(); + void redraw_events(); void set_zoom( int a_zoom ); void set_snap( int a_snap ); void set_note_length( int a_note_length ); + void set_ignore_redraw(bool a_ignore); void set_scale( int a_scale ); void set_key( int a_key ); void update_sizes(); - void draw_background(); + void update_background(); + void draw_background_on_pixmap(); void draw_events_on_pixmap(); void draw_selection_on_window(); void update_pixmap();