[alsa-devel] [PATCH v3 1/2] amidi: add delay option

Felipe Ferreri Tonello eu at felipetonello.com
Mon Aug 15 17:48:51 CEST 2016



On 15/08/16 16:36, Felipe F. Tonello wrote:
> This patch adds a new options to amidi tool to add a delay (in milliseconds)
> to each SysEx message.
> 
> This is very useful when sending firmware updates to a remote device via SysEx
> or any other use that requires this delay in between messages.
> 
> Signed-off-by: Felipe F. Tonello <eu at felipetonello.com>
> ---
>  amidi/amidi.1 | 14 ++++++++++++++
>  amidi/amidi.c | 38 +++++++++++++++++++++++++++++++++-----
>  2 files changed, 47 insertions(+), 5 deletions(-)
> 
> diff --git a/amidi/amidi.1 b/amidi/amidi.1
> index 1b4cfb1ea956..391008177610 100644
> --- a/amidi/amidi.1
> +++ b/amidi/amidi.1
> @@ -111,6 +111,12 @@ to stop receiving data.
>  Does not ignore Active Sensing bytes (FEh) when saving or printing
>  received MIDI commands.
>  
> +.TP
> +.I \-D, \-\-delay=mseconds
> +Adds a delay in between each SysEx message sent to a device. It is
> +useful when sending firmware updates via SysEx messages to a remote
> +device.
> +
>  .SH EXAMPLES
>  
>  .TP
> @@ -121,6 +127,14 @@ to port
>  .I hw:0.
>  
>  .TP
> +.B amidi \-p hw:1,0,0 -s firmware.syx \-D 100
> +will send the MIDI commands in
> +.I firmware.syx
> +to port
> +.I hw:1,0,0
> +with 100 milliseconds delay in between each SysEx message.
> +
> +.TP
>  .B amidi \-S 'F0 43 10 4C 00 00 7E 00 F7'
>  sends an XG Reset to the default port.
>  
> diff --git a/amidi/amidi.c b/amidi/amidi.c
> index cedf18c5fd39..a1cb77f362bd 100644
> --- a/amidi/amidi.c
> +++ b/amidi/amidi.c
> @@ -48,6 +48,7 @@ static int receive_file;
>  static int dump;
>  static int timeout;
>  static int stop;
> +static int delay;
>  static snd_rawmidi_t *input, **inputp;
>  static snd_rawmidi_t *output, **outputp;
>  
> @@ -77,7 +78,8 @@ static void usage(void)
>  		"-d, --dump             print received data as hexadecimal bytes\n"
>  		"-t, --timeout=seconds  exits when no data has been received\n"
>  		"                       for the specified duration\n"
> -		"-a, --active-sensing   don't ignore active sensing bytes\n");
> +		"-a, --active-sensing   don't ignore active sensing bytes\n"
> +		"-D, --delay=mseconds   delay in between each SysEx message\n");
>  }
>  
>  static void version(void)
> @@ -406,7 +408,7 @@ static void add_send_hex_data(const char *str)
>  
>  int main(int argc, char *argv[])
>  {
> -	static const char short_options[] = "hVlLp:s:r:S::dt:a";
> +	static const char short_options[] = "hVlLp:s:r:S::dt:aD:";
>  	static const struct option long_options[] = {
>  		{"help", 0, NULL, 'h'},
>  		{"version", 0, NULL, 'V'},
> @@ -419,6 +421,7 @@ int main(int argc, char *argv[])
>  		{"dump", 0, NULL, 'd'},
>  		{"timeout", 1, NULL, 't'},
>  		{"active-sensing", 0, NULL, 'a'},
> +		{"delay", 1, NULL, 'D'},
>  		{ }
>  	};
>  	int c, err, ok = 0;
> @@ -463,6 +466,9 @@ int main(int argc, char *argv[])
>  		case 'a':
>  			ignore_active_sensing = 0;
>  			break;
> +		case 'D':
> +			delay = atoi(optarg);
> +			break;
>  		default:
>  			error("Try `amidi --help' for more information.");
>  			return 1;
> @@ -538,9 +544,31 @@ int main(int argc, char *argv[])
>  			error("cannot set blocking mode: %s", snd_strerror(err));
>  			goto _exit;
>  		}
> -		if ((err = snd_rawmidi_write(output, send_data, send_data_length)) < 0) {
> -			error("cannot send data: %s", snd_strerror(err));
> -			goto _exit;
> +		if (!delay) {
> +			if ((err = snd_rawmidi_write(output, send_data, send_data_length)) < 0) {
> +				error("cannot send data: %s", snd_strerror(err));
> +				return err;
> +			}
> +		} else {
> +			char *data = send_data;
> +
> +			while (data < (send_data + send_data_length)) {
> +				int len;
> +
> +				if (data > send_data)
> +					usleep(delay * 1000);
> +
> +				/* find end of SysEx */
> +				len = (char *)memchr(data, 0xf7, (send_data + send_data_length) - data)
> +					- data + 1;

There is a bug in here if memchr returns NULL. I will fix it and send a v4.

> +
> +				if ((err = snd_rawmidi_write(output, data, len)) < 0) {
> +					error("cannot send data: %s", snd_strerror(err));
> +					return err;
> +				}
> +
> +				data += len;
> +			}
>  		}
>  	}
>  
> 

-- 
Felipe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0x92698E6A.asc
Type: application/pgp-keys
Size: 7195 bytes
Desc: not available
URL: <http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20160815/0aa25e71/attachment-0001.bin>


More information about the Alsa-devel mailing list