#include #include #include #include #include #include #include static int set_realtime_priority( void ) { struct sched_param schp; memset( &schp, 0, sizeof( schp ) ); schp.sched_priority = sched_get_priority_max( SCHED_FIFO ); if( sched_setscheduler( 0, SCHED_FIFO, &schp ) != 0 ) { return -1; } return 0; } int main( int argc, char **argv ) { int outchan = 1; int mfd; /** * We try to set ourselves at realtime priority, * but we can still run if we don't get it. */ if( set_realtime_priority() < 0 ) { fprintf( stderr, "miditool: Can't set realtime priority, " "latency may suffer.\n" "miditool: You can run as root to fix this.\n" ); } mfd = open( "/dev/midi0", O_RDWR ); if( mfd < 0 ) { fprintf( stderr, "miditool: Can't open device /dev/midi0.\n" ); return 1; } if( argc > 1 ) { outchan = atoi( argv[ 1 ] ) - 1; if( outchan < 0 ) outchan = 0; if( outchan > 15 ) outchan = 15; } fprintf( stderr, "miditool: Converting all messages to MIDI channel %d\n", outchan + 1 ); for(;;) { unsigned char buff; int command; /** * Only need one byte at a time. * (that's all my driver gives me anyway) */ if( read( mfd, &buff, 1 ) < 0 ) break; /* Drop active sensing messages */ if( buff == 0xfe ) continue; /* Grab command information. */ command = buff >> 4; /* Only act on the few MIDI messages I care about */ if( command >= 8 && command <= 11 ) { buff = (command << 4) | outchan; } /* Output our (potentially modified) byte. */ write( mfd, &buff, 1 ); } return 0; }