@ -16,6 +16,13 @@
* along with this program . If not , see < http : / / www . gnu . org / licenses / > .
*/
/** @file microx.c
* MicroX - specific functions .
*
* This module provides helper functions to deal with a Korg microX
* synthesizer .
*/
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
@ -26,9 +33,18 @@
# include <sysex.h>
/**
* Identify a connected microX device .
* This function check whether the device connected to the MIDI
* port is a Korg microX synthesizer .
*
* @ param [ in ] midi The MIDI port .
* @ param [ out ] version A pointer to a kmx_microx_version structure
* to be filled in with informations from the
* device ; may be @ c NULL .
*
* @ return
* - 0 if the port is connected to a device which successfully
* identified itself as a microX device ;
* - @ e KMX_OK if the port is connected to a device which
* successfully identified itself as a microX device ;
* - @ e KMX_IO_ERROR if an I / O error occured ;
* - @ e KMX_INVALID_REPLY if the device replied incorrectly :
* - @ e KMX_NOT_KORG is the device did not identify itself as
@ -61,12 +77,21 @@ kmx_microx_identify(midi_io_t *midi,
version - > build = ( devid . version > > 24 ) & 0xFF ;
}
return 0 ;
return KMX_OK ;
}
/**
* Get the microX current status .
* This function gets the current status of the connected microX
* synthesizer .
*
* @ param [ in ] midi The MIDI port .
* @ param [ out ] status A pointer to a kmx_microx_status structure
* to be filled in with the status data
* received from the microX ; may be @ c NULL .
*
* @ return
* - 0 if the query was successful ;
* - @ e KMX_OK if the query was successful ;
* - @ e KMX_IO_ERROR if an I / O error occured ;
* - @ e KMX_NOT_KORG if the reply did not come from a Korg device ;
* - @ e KMX_INVALID_REPLY if the device replied incorrectly .
@ -178,10 +203,21 @@ kmx_microx_query_status(midi_io_t *midi,
s - > ext_ctrl . current = reply [ 24 ] ;
}
return 0 ;
return KMX_OK ;
}
/**
* Get an error message .
* This function translates an error code returned by other
* functions of this module to an error message .
*
* If the error happens to be a MIDI I / O error , this function
* calls the midi_error ( ) function to get a meaningful
* message from the underlying MIDI API .
*
* @ param [ in ] midi The MIDI port used to talk to the microX .
* @ param [ in ] e The error code to lookup .
*
* @ return
* A static string containing the user - readable error message .
*/
@ -256,6 +292,12 @@ static struct {
} ;
/**
* Parse a string as a positive integer .
* This function parses the given string as a positive integer
* value .
*
* @ param [ in ] s The string to parse .
*
* @ return
* - The positive integer value contained in @ a s ;
* - - 1 if @ a s could not be parsed as a positive integer value .
@ -279,9 +321,43 @@ parse_int(const char *s)
}
/**
* Parse a string as a dump / load request to the microX .
* This function translates a string to a formal representation
* of a dump or load parameter request to a microX device .
*
* If the request string is valid and successfully parsed , the
* function fills in a kmx_microx_dump structure which may then
* be used in a call to kmx_microx_dump ( ) or kmx_microx_load ( ) .
*
* The request string should start with a single letter
* indicating the type of memory to dump or load : ' P ' for programs ,
* ' C ' for combinations , ' M ' for multis , ' D ' for drumkits ,
* ' A ' for arpeggio patterns , or ' E ' for external controllers sets .
* It must be followed by a single uppercase letter indicating the
* bank ( only for programs and combinations ) , and up to three
* decimal digits indicating the slot number ( counting from one ) .
*
* An asterisk may be used instead of the program number , in that
* case the microX will be instructed to dump all slots in the
* bank . For programs and combinations , an asterisk may also be
* used instead of the bank letter @ e and the program number , in
* that case the microX will be instructed to dump all slots in
* all program or combination banks .
*
* For example :
*
* - @ c " PA123 " means " dump program #123 of bank A " ;
* - @ c " M17 " means " dump multi #17 " ;
* - @ c " CB* " means " dump all combinations in bank B " ;
* - @ c " C* " means " dump all combinations in all banks " ;
* - @ c " D* " means " dump all drumkits " .
*
* @ param [ in ] what The request string to parse .
* @ param [ out ] The kmx_microx_dump structure to fill in .
*
* @ return
* - 0 if the dump request was successfully parsed .
* - - 1 if the dump request is invalid .
* - @ e KMX_OK if the dump request was successfully parsed .
* - @ e KMX_INVALID_QUERY if the dump request is invalid .
*/
int
kmx_microx_parse_dump_request ( const char * what , struct kmx_microx_dump * dump )
@ -289,7 +365,7 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
int val , ret ;
char bank ;
ret = 0 ;
ret = KMX_OK ;
switch ( * what + + ) {
case ' P ' :
@ -304,10 +380,10 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
else if ( ( val = parse_int ( what ) ) > = 1 & & val < = MICROX_BANK_SIZE )
dump - > program = val - 1 ;
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
}
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
break ;
case ' C ' :
@ -322,10 +398,10 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
else if ( ( val = parse_int ( what ) ) > = 1 & & val < = MICROX_BANK_SIZE )
dump - > program = val - 1 ;
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
}
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
break ;
case ' M ' :
@ -335,7 +411,7 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
else if ( ( val = parse_int ( what ) ) > = 1 & & val < = MICROX_N_MULTI )
dump - > program = val - 1 ;
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
break ;
case ' D ' :
@ -345,7 +421,7 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
else if ( ( val = parse_int ( what ) ) > = 1 & & val < = MICROX_N_DRUMKIT )
dump - > program = val - 1 ;
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
break ;
case ' A ' :
@ -355,7 +431,7 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
else if ( ( val = parse_int ( what ) ) > = 1 & & val < = MICROX_N_ARPEGGIO )
dump - > program = val - 1 ;
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
break ;
case ' E ' :
@ -365,17 +441,25 @@ kmx_microx_parse_dump_request(const char *what, struct kmx_microx_dump *dump)
else if ( ( val = parse_int ( what ) ) > = 1 & & val < = MICROX_N_EXTSET )
dump - > program = val - 1 ;
else
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
break ;
default :
ret = - 1 ;
ret = KMX_INVALID_QUERY ;
}
return ret ;
}
/**
* Get the size of a microX data dump .
* Given a formal dump specification as returned by the
* kmx_microx_parse_dump_request ( ) function , this function
* returns the expected size of the corresponding dump .
*
* @ param [ in ] dump A kmx_microx_dump structure representing
* a dump request .
*
* @ return
* The expected size of the specified data dump .
*/
@ -430,9 +514,21 @@ kmx_microx_get_dump_size(struct kmx_microx_dump *dump)
}
/**
* Translate a dump request into actual MIDI bytes .
* Given a formal dump specification as returned by the
* kmx_microx_parse_dump_request ( ) function , this function
* translates the request into the appropriate MIDI bytes
* that can be received by a microX synthesizer .
*
* @ param [ in ] dump A kmx_microx_dump structure
* representing a dump request .
* @ param [ out ] buffer A buffer to be filled in with the
* appropriate MIDI bytes ; this buffer
* should be at least 4 four bytes long .
*
* @ return
* - 0 if the operation was successful ;
* - - 1 if an error occured .
* - @ e KMX_OK if the operation was successful ;
* - @ e KMX_INVALID_QUERY if an error occured .
*
* The current implementation is always successful .
*/
@ -509,10 +605,21 @@ get_dump_parameters(struct kmx_microx_dump *dump,
break ;
}
return 0 ;
return KMX_OK ;
}
/**
* Read a microX data dump .
* This function reads data from a MIDI port and , if it corresponds
* to a SysEx message announcing a Korg microX data dump , translates
* it from the MIDI encoding used to transmit it .
*
* @ param [ in ] midi The MIDI port to read from .
* @ param [ in ] reply_code The expected function code of the SysEx
* message to read .
* @ param [ out ] data The buffer where to store the dump .
* @ param [ in ] len The size of the @ a data buffer .
*
* @ return
* - The count of data bytes read and stored in the @ a data buffer ;
* - @ e KMX_IO_ERROR if an I / O error occured ;
@ -581,6 +688,17 @@ kmx_microx_read_dump(midi_io_t *midi,
}
/**
* Dump memory slot ( s ) from a microX device .
* This function sends a parameter dump request to the
* connected microX synthesizer and gets the dump data
* in reply .
*
* @ param [ in ] midi The MIDI port .
* @ param [ in ] dump A kmx_microx_dump structure representing
* the dump request .
* @ param [ out ] data The buffer where to store the dump .
* @ param [ in ] len The size of the @ a data buffer .
*
* @ return
* - The number of bytes read and stored in the @ a data buffer ;
* - @ e KMX_IO_ERROR if an I / O error occured ;
@ -608,7 +726,7 @@ kmx_microx_dump(midi_io_t *midi,
0x00 , /* Dump parameter 3 */
0xF7 /* SysEx message end */ } ;
if ( get_dump_parameters ( dump , & ( query [ 4 ] ) ) = = - 1 )
if ( get_dump_parameters ( dump , & ( query [ 4 ] ) ) = = KMX_INVALID_QUERY )
return KMX_INVALID_QUERY ;
if ( len < kmx_microx_get_dump_size ( dump ) )
@ -621,6 +739,17 @@ kmx_microx_dump(midi_io_t *midi,
}
/**
* Load a memory slot to a microX device .
* This function loads the provided data to a memory slot of
* the microX synthesizer .
*
* @ param [ in ] midi The MIDI port .
* @ param [ in ] dump A kmx_microx_dump structure indicating the
* memory slot to load the data into .
* @ param [ in ] data The data to load .
* @ param [ in ] len The number of bytes from the @ a data buffer
* to send to the device .
*
* @ return
* - @ e KMX_OK if the load operation completed successfully ;
* - @ e KMX_IO_ERROR if an I / O error occured ;
@ -654,7 +783,7 @@ kmx_microx_load(midi_io_t *midi,
0x00 , /* Dump parameter 3 */ } ;
unsigned char reply [ 7 ] ;
if ( get_dump_parameters ( dump , & ( buffer [ 4 ] ) ) = = - 1 )
if ( get_dump_parameters ( dump , & ( buffer [ 4 ] ) ) = = KMX_INVALID_QUERY )
return KMX_INVALID_QUERY ;
if ( len < kmx_microx_get_dump_size ( dump ) )