All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/2] amidi delay option
@ 2016-08-23 14:09 Felipe F. Tonello
  2016-08-23 14:09 ` [PATCH v6 1/2] amidi: add " Felipe F. Tonello
  2016-08-23 14:09 ` [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names Felipe F. Tonello
  0 siblings, 2 replies; 7+ messages in thread
From: Felipe F. Tonello @ 2016-08-23 14:09 UTC (permalink / raw)
  To: alsa-devel

Small improvement to amidi, adding useful functionality.

changes from v5:
 * wait until MIDI message is competely sent to sleep

changes from v4:
 * simplified code

changes from v3:
 * fixed a bug if memchr() returns NULL

changes from v2:
 * only check of end of sysex (0xf7)
 * use memchr() instead of direct loop approach
 * fixed commit message

changes from v1:
 * remove delay in between any MIDI message, only SysEx
 * added patch to use getopt_long() arguments

Felipe F. Tonello (2):
  amidi: add delay option
  amidi: use GNU getopt_long() proper argument names

 amidi/amidi.1 | 14 ++++++++++
 amidi/amidi.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 79 insertions(+), 17 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v6 1/2] amidi: add delay option
  2016-08-23 14:09 [PATCH v6 0/2] amidi delay option Felipe F. Tonello
@ 2016-08-23 14:09 ` Felipe F. Tonello
  2016-08-29 23:19   ` Takashi Sakamoto
  2016-08-23 14:09 ` [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names Felipe F. Tonello
  1 sibling, 1 reply; 7+ messages in thread
From: Felipe F. Tonello @ 2016-08-23 14:09 UTC (permalink / raw)
  To: alsa-devel

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@felipetonello.com>
---
 amidi/amidi.1 | 14 ++++++++++++++
 amidi/amidi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/amidi/amidi.1 b/amidi/amidi.1
index 86beb27a1e3b..4ca2164788f1 100644
--- a/amidi/amidi.1
+++ b/amidi/amidi.1
@@ -120,6 +120,12 @@ received MIDI commands.
 Does not ignore Clock bytes (F8h) 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
@@ -130,6 +136,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 c20512cc96a7..d0dbb322f80a 100644
--- a/amidi/amidi.c
+++ b/amidi/amidi.c
@@ -52,6 +52,7 @@ static int receive_file;
 static int dump;
 static float timeout;
 static int stop;
+static int delay;
 static snd_rawmidi_t *input, **inputp;
 static snd_rawmidi_t *output, **outputp;
 
@@ -82,7 +83,8 @@ static void usage(void)
 		"-t, --timeout=seconds  exits when no data has been received\n"
 		"                       for the specified duration\n"
 		"-a, --active-sensing   include active sensing bytes\n"
-		"-c, --clock            include clock bytes\n");
+		"-c, --clock            include clock bytes\n"
+		"-D, --delay=mseconds   delay in between each SysEx message\n");
 }
 
 static void version(void)
@@ -411,7 +413,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:ac";
+	static const char short_options[] = "hVlLp:s:r:S::dt:acD:";
 	static const struct option long_options[] = {
 		{"help", 0, NULL, 'h'},
 		{"version", 0, NULL, 'V'},
@@ -425,6 +427,7 @@ int main(int argc, char *argv[])
 		{"timeout", 1, NULL, 't'},
 		{"active-sensing", 0, NULL, 'a'},
 		{"clock", 0, NULL, 'c'},
+		{"delay", 1, NULL, 'D'},
 		{ }
 	};
 	int c, err, ok = 0;
@@ -474,6 +477,9 @@ int main(int argc, char *argv[])
 		case 'c':
 			ignore_clock = 0;
 			break;
+		case 'D':
+			delay = atoi(optarg);
+			break;
 		default:
 			error("Try `amidi --help' for more information.");
 			return 1;
@@ -549,9 +555,51 @@ 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;
+			size_t buffer_size;
+			snd_rawmidi_params_t *param;
+			snd_rawmidi_status_t *st;
+
+			snd_rawmidi_status_malloc(&st);
+
+			snd_rawmidi_params_malloc(&param);
+			snd_rawmidi_params_current(output, param);
+			buffer_size = snd_rawmidi_params_get_buffer_size(param);
+			snd_rawmidi_params_free(param);
+
+			while (data < (send_data + send_data_length)) {
+				int len = send_data + send_data_length - data;
+				char *temp;
+
+				if (data > send_data) {
+					snd_rawmidi_status(output, st);
+					do {
+						/* 320 µs per byte as noted in Page 1 of MIDI spec */
+						usleep((buffer_size - snd_rawmidi_status_get_avail(st)) * 320);
+						snd_rawmidi_status(output, st);
+					} while(snd_rawmidi_status_get_avail(st) < buffer_size);
+					usleep(delay * 1000);
+				}
+
+				/* find end of SysEx */
+				if ((temp = memchr(data, 0xf7, len)) != NULL)
+					len = temp - data + 1;
+
+				if ((err = snd_rawmidi_write(output, data, len)) < 0) {
+					error("cannot send data: %s", snd_strerror(err));
+					return err;
+				}
+
+				data += len;
+			}
+
+			snd_rawmidi_status_free(st);
 		}
 	}
 
-- 
2.9.3

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names
  2016-08-23 14:09 [PATCH v6 0/2] amidi delay option Felipe F. Tonello
  2016-08-23 14:09 ` [PATCH v6 1/2] amidi: add " Felipe F. Tonello
@ 2016-08-23 14:09 ` Felipe F. Tonello
  2016-08-29 23:22   ` Takashi Sakamoto
  1 sibling, 1 reply; 7+ messages in thread
From: Felipe F. Tonello @ 2016-08-23 14:09 UTC (permalink / raw)
  To: alsa-devel

This has no affect besides more clarity to the code.

Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
---
 amidi/amidi.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/amidi/amidi.c b/amidi/amidi.c
index d0dbb322f80a..088da56e2139 100644
--- a/amidi/amidi.c
+++ b/amidi/amidi.c
@@ -415,19 +415,19 @@ int main(int argc, char *argv[])
 {
 	static const char short_options[] = "hVlLp:s:r:S::dt:acD:";
 	static const struct option long_options[] = {
-		{"help", 0, NULL, 'h'},
-		{"version", 0, NULL, 'V'},
-		{"list-devices", 0, NULL, 'l'},
-		{"list-rawmidis", 0, NULL, 'L'},
-		{"port", 1, NULL, 'p'},
-		{"send", 1, NULL, 's'},
-		{"receive", 1, NULL, 'r'},
-		{"send-hex", 2, NULL, 'S'},
-		{"dump", 0, NULL, 'd'},
-		{"timeout", 1, NULL, 't'},
-		{"active-sensing", 0, NULL, 'a'},
-		{"clock", 0, NULL, 'c'},
-		{"delay", 1, NULL, 'D'},
+		{"help", no_argument, NULL, 'h'},
+		{"version", no_argument, NULL, 'V'},
+		{"list-devices", no_argument, NULL, 'l'},
+		{"list-rawmidis", no_argument, NULL, 'L'},
+		{"port", required_argument, NULL, 'p'},
+		{"send", required_argument, NULL, 's'},
+		{"receive", required_argument, NULL, 'r'},
+		{"send-hex", optional_argument, NULL, 'S'},
+		{"dump", no_argument, NULL, 'd'},
+		{"timeout", required_argument, NULL, 't'},
+		{"active-sensing", no_argument, NULL, 'a'},
+		{"clock", no_argument, NULL, 'c'},
+		{"delay", required_argument, NULL, 'D'},
 		{ }
 	};
 	int c, err, ok = 0;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 1/2] amidi: add delay option
  2016-08-23 14:09 ` [PATCH v6 1/2] amidi: add " Felipe F. Tonello
@ 2016-08-29 23:19   ` Takashi Sakamoto
  2016-08-30 10:19     ` Felipe Ferreri Tonello
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Sakamoto @ 2016-08-29 23:19 UTC (permalink / raw)
  To: Felipe F. Tonello, alsa-devel

Hi,

On Aug 23 2016 23:09, 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@felipetonello.com>
> ---
>  amidi/amidi.1 | 14 ++++++++++++++
>  amidi/amidi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 67 insertions(+), 5 deletions(-)
> 
> diff --git a/amidi/amidi.1 b/amidi/amidi.1
> index 86beb27a1e3b..4ca2164788f1 100644
> --- a/amidi/amidi.1
> +++ b/amidi/amidi.1
> @@ -120,6 +120,12 @@ received MIDI commands.
>  Does not ignore Clock bytes (F8h) 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.
> +

I think it's helpful to name this option so that it keeps intervals
somewhat between each system exclusives. For example, how do you think
about using 'sysex-interval'?

>  .SH EXAMPLES
>  
>  .TP
> @@ -130,6 +136,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 c20512cc96a7..d0dbb322f80a 100644
> --- a/amidi/amidi.c
> +++ b/amidi/amidi.c
> @@ -52,6 +52,7 @@ static int receive_file;
>  static int dump;
>  static float timeout;
>  static int stop;
> +static int delay;
>  static snd_rawmidi_t *input, **inputp;
>  static snd_rawmidi_t *output, **outputp;
>  
> @@ -82,7 +83,8 @@ static void usage(void)
>  		"-t, --timeout=seconds  exits when no data has been received\n"
>  		"                       for the specified duration\n"
>  		"-a, --active-sensing   include active sensing bytes\n"
> -		"-c, --clock            include clock bytes\n");
> +		"-c, --clock            include clock bytes\n"
> +		"-D, --delay=mseconds   delay in between each SysEx message\n");
>  }
>  
>  static void version(void)
> @@ -411,7 +413,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:ac";
> +	static const char short_options[] = "hVlLp:s:r:S::dt:acD:";
>  	static const struct option long_options[] = {
>  		{"help", 0, NULL, 'h'},
>  		{"version", 0, NULL, 'V'},
> @@ -425,6 +427,7 @@ int main(int argc, char *argv[])
>  		{"timeout", 1, NULL, 't'},
>  		{"active-sensing", 0, NULL, 'a'},
>  		{"clock", 0, NULL, 'c'},
> +		{"delay", 1, NULL, 'D'},
>  		{ }
>  	};
>  	int c, err, ok = 0;
> @@ -474,6 +477,9 @@ int main(int argc, char *argv[])
>  		case 'c':
>  			ignore_clock = 0;
>  			break;
> +		case 'D':
> +			delay = atoi(optarg);
> +			break;
>  		default:
>  			error("Try `amidi --help' for more information.");
>  			return 1;
> @@ -549,9 +555,51 @@ 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;
> +			size_t buffer_size;
> +			snd_rawmidi_params_t *param;
> +			snd_rawmidi_status_t *st;
> +
> +			snd_rawmidi_status_malloc(&st);
> +
> +			snd_rawmidi_params_malloc(&param);
> +			snd_rawmidi_params_current(output, param);
> +			buffer_size = snd_rawmidi_params_get_buffer_size(param);
> +			snd_rawmidi_params_free(param);
> +
> +			while (data < (send_data + send_data_length)) {
> +				int len = send_data + send_data_length - data;
> +				char *temp;
> +
> +				if (data > send_data) {
> +					snd_rawmidi_status(output, st);
> +					do {
> +						/* 320 µs per byte as noted in Page 1 of MIDI spec */
> +						usleep((buffer_size - snd_rawmidi_status_get_avail(st)) * 320);
> +						snd_rawmidi_status(output, st);
> +					} while(snd_rawmidi_status_get_avail(st) < buffer_size);
> +					usleep(delay * 1000);
> +				}
> +
> +				/* find end of SysEx */
> +				if ((temp = memchr(data, 0xf7, len)) != NULL)
> +					len = temp - data + 1;
> +
> +				if ((err = snd_rawmidi_write(output, data, len)) < 0) {
> +					error("cannot send data: %s", snd_strerror(err));
> +					return err;
> +				}
> +
> +				data += len;
> +			}
> +
> +			snd_rawmidi_status_free(st);
>  		}
>  	}

In my opinion, it's better to split function specific to this purpose
and call it here. An appropriate name of the function might help readers.


Regards

Takashi Sakamoto
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names
  2016-08-23 14:09 ` [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names Felipe F. Tonello
@ 2016-08-29 23:22   ` Takashi Sakamoto
  2016-08-30 10:18     ` Felipe Ferreri Tonello
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Sakamoto @ 2016-08-29 23:22 UTC (permalink / raw)
  To: Felipe F. Tonello, alsa-devel

On Aug 23 2016 23:09, Felipe F. Tonello wrote:
> This has no affect besides more clarity to the code.
> 
> Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
> ---
>  amidi/amidi.c | 26 +++++++++++++-------------
>  1 file changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/amidi/amidi.c b/amidi/amidi.c
> index d0dbb322f80a..088da56e2139 100644
> --- a/amidi/amidi.c
> +++ b/amidi/amidi.c
> @@ -415,19 +415,19 @@ int main(int argc, char *argv[])
>  {
>  	static const char short_options[] = "hVlLp:s:r:S::dt:acD:";
>  	static const struct option long_options[] = {
> -		{"help", 0, NULL, 'h'},
> -		{"version", 0, NULL, 'V'},
> -		{"list-devices", 0, NULL, 'l'},
> -		{"list-rawmidis", 0, NULL, 'L'},
> -		{"port", 1, NULL, 'p'},
> -		{"send", 1, NULL, 's'},
> -		{"receive", 1, NULL, 'r'},
> -		{"send-hex", 2, NULL, 'S'},
> -		{"dump", 0, NULL, 'd'},
> -		{"timeout", 1, NULL, 't'},
> -		{"active-sensing", 0, NULL, 'a'},
> -		{"clock", 0, NULL, 'c'},
> -		{"delay", 1, NULL, 'D'},
> +		{"help", no_argument, NULL, 'h'},
> +		{"version", no_argument, NULL, 'V'},
> +		{"list-devices", no_argument, NULL, 'l'},
> +		{"list-rawmidis", no_argument, NULL, 'L'},
> +		{"port", required_argument, NULL, 'p'},
> +		{"send", required_argument, NULL, 's'},
> +		{"receive", required_argument, NULL, 'r'},
> +		{"send-hex", optional_argument, NULL, 'S'},
> +		{"dump", no_argument, NULL, 'd'},
> +		{"timeout", required_argument, NULL, 't'},
> +		{"active-sensing", no_argument, NULL, 'a'},
> +		{"clock", no_argument, NULL, 'c'},
> +		{"delay", required_argument, NULL, 'D'},
>  		{ }
>  	};
>  	int c, err, ok = 0;

This patch should be posted separately from this patchset, because it's
just for code improvement regardless of your new feature. This patch
might be independently merged without long discussions.


Regards

Takashi Sakamoto

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names
  2016-08-29 23:22   ` Takashi Sakamoto
@ 2016-08-30 10:18     ` Felipe Ferreri Tonello
  0 siblings, 0 replies; 7+ messages in thread
From: Felipe Ferreri Tonello @ 2016-08-30 10:18 UTC (permalink / raw)
  To: Takashi Sakamoto, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 1948 bytes --]

Hi Takashi,

On 30/08/16 00:22, Takashi Sakamoto wrote:
> On Aug 23 2016 23:09, Felipe F. Tonello wrote:
>> This has no affect besides more clarity to the code.
>>
>> Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
>> ---
>>  amidi/amidi.c | 26 +++++++++++++-------------
>>  1 file changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/amidi/amidi.c b/amidi/amidi.c
>> index d0dbb322f80a..088da56e2139 100644
>> --- a/amidi/amidi.c
>> +++ b/amidi/amidi.c
>> @@ -415,19 +415,19 @@ int main(int argc, char *argv[])
>>  {
>>  	static const char short_options[] = "hVlLp:s:r:S::dt:acD:";
>>  	static const struct option long_options[] = {
>> -		{"help", 0, NULL, 'h'},
>> -		{"version", 0, NULL, 'V'},
>> -		{"list-devices", 0, NULL, 'l'},
>> -		{"list-rawmidis", 0, NULL, 'L'},
>> -		{"port", 1, NULL, 'p'},
>> -		{"send", 1, NULL, 's'},
>> -		{"receive", 1, NULL, 'r'},
>> -		{"send-hex", 2, NULL, 'S'},
>> -		{"dump", 0, NULL, 'd'},
>> -		{"timeout", 1, NULL, 't'},
>> -		{"active-sensing", 0, NULL, 'a'},
>> -		{"clock", 0, NULL, 'c'},
>> -		{"delay", 1, NULL, 'D'},
>> +		{"help", no_argument, NULL, 'h'},
>> +		{"version", no_argument, NULL, 'V'},
>> +		{"list-devices", no_argument, NULL, 'l'},
>> +		{"list-rawmidis", no_argument, NULL, 'L'},
>> +		{"port", required_argument, NULL, 'p'},
>> +		{"send", required_argument, NULL, 's'},
>> +		{"receive", required_argument, NULL, 'r'},
>> +		{"send-hex", optional_argument, NULL, 'S'},
>> +		{"dump", no_argument, NULL, 'd'},
>> +		{"timeout", required_argument, NULL, 't'},
>> +		{"active-sensing", no_argument, NULL, 'a'},
>> +		{"clock", no_argument, NULL, 'c'},
>> +		{"delay", required_argument, NULL, 'D'},
>>  		{ }
>>  	};
>>  	int c, err, ok = 0;
> 
> This patch should be posted separately from this patchset, because it's
> just for code improvement regardless of your new feature. This patch
> might be independently merged without long discussions.

Ok.

-- 
Felipe

[-- Attachment #2: 0x92698E6A.asc --]
[-- Type: application/pgp-keys, Size: 7177 bytes --]

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 1/2] amidi: add delay option
  2016-08-29 23:19   ` Takashi Sakamoto
@ 2016-08-30 10:19     ` Felipe Ferreri Tonello
  0 siblings, 0 replies; 7+ messages in thread
From: Felipe Ferreri Tonello @ 2016-08-30 10:19 UTC (permalink / raw)
  To: Takashi Sakamoto, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 5318 bytes --]

Hi Takashi,

On 30/08/16 00:19, Takashi Sakamoto wrote:
> Hi,
> 
> On Aug 23 2016 23:09, 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@felipetonello.com>
>> ---
>>  amidi/amidi.1 | 14 ++++++++++++++
>>  amidi/amidi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
>>  2 files changed, 67 insertions(+), 5 deletions(-)
>>
>> diff --git a/amidi/amidi.1 b/amidi/amidi.1
>> index 86beb27a1e3b..4ca2164788f1 100644
>> --- a/amidi/amidi.1
>> +++ b/amidi/amidi.1
>> @@ -120,6 +120,12 @@ received MIDI commands.
>>  Does not ignore Clock bytes (F8h) 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.
>> +
> 
> I think it's helpful to name this option so that it keeps intervals
> somewhat between each system exclusives. For example, how do you think
> about using 'sysex-interval'?

Sure.

> 
>>  .SH EXAMPLES
>>  
>>  .TP
>> @@ -130,6 +136,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 c20512cc96a7..d0dbb322f80a 100644
>> --- a/amidi/amidi.c
>> +++ b/amidi/amidi.c
>> @@ -52,6 +52,7 @@ static int receive_file;
>>  static int dump;
>>  static float timeout;
>>  static int stop;
>> +static int delay;
>>  static snd_rawmidi_t *input, **inputp;
>>  static snd_rawmidi_t *output, **outputp;
>>  
>> @@ -82,7 +83,8 @@ static void usage(void)
>>  		"-t, --timeout=seconds  exits when no data has been received\n"
>>  		"                       for the specified duration\n"
>>  		"-a, --active-sensing   include active sensing bytes\n"
>> -		"-c, --clock            include clock bytes\n");
>> +		"-c, --clock            include clock bytes\n"
>> +		"-D, --delay=mseconds   delay in between each SysEx message\n");
>>  }
>>  
>>  static void version(void)
>> @@ -411,7 +413,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:ac";
>> +	static const char short_options[] = "hVlLp:s:r:S::dt:acD:";
>>  	static const struct option long_options[] = {
>>  		{"help", 0, NULL, 'h'},
>>  		{"version", 0, NULL, 'V'},
>> @@ -425,6 +427,7 @@ int main(int argc, char *argv[])
>>  		{"timeout", 1, NULL, 't'},
>>  		{"active-sensing", 0, NULL, 'a'},
>>  		{"clock", 0, NULL, 'c'},
>> +		{"delay", 1, NULL, 'D'},
>>  		{ }
>>  	};
>>  	int c, err, ok = 0;
>> @@ -474,6 +477,9 @@ int main(int argc, char *argv[])
>>  		case 'c':
>>  			ignore_clock = 0;
>>  			break;
>> +		case 'D':
>> +			delay = atoi(optarg);
>> +			break;
>>  		default:
>>  			error("Try `amidi --help' for more information.");
>>  			return 1;
>> @@ -549,9 +555,51 @@ 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;
>> +			size_t buffer_size;
>> +			snd_rawmidi_params_t *param;
>> +			snd_rawmidi_status_t *st;
>> +
>> +			snd_rawmidi_status_malloc(&st);
>> +
>> +			snd_rawmidi_params_malloc(&param);
>> +			snd_rawmidi_params_current(output, param);
>> +			buffer_size = snd_rawmidi_params_get_buffer_size(param);
>> +			snd_rawmidi_params_free(param);
>> +
>> +			while (data < (send_data + send_data_length)) {
>> +				int len = send_data + send_data_length - data;
>> +				char *temp;
>> +
>> +				if (data > send_data) {
>> +					snd_rawmidi_status(output, st);
>> +					do {
>> +						/* 320 µs per byte as noted in Page 1 of MIDI spec */
>> +						usleep((buffer_size - snd_rawmidi_status_get_avail(st)) * 320);
>> +						snd_rawmidi_status(output, st);
>> +					} while(snd_rawmidi_status_get_avail(st) < buffer_size);
>> +					usleep(delay * 1000);
>> +				}
>> +
>> +				/* find end of SysEx */
>> +				if ((temp = memchr(data, 0xf7, len)) != NULL)
>> +					len = temp - data + 1;
>> +
>> +				if ((err = snd_rawmidi_write(output, data, len)) < 0) {
>> +					error("cannot send data: %s", snd_strerror(err));
>> +					return err;
>> +				}
>> +
>> +				data += len;
>> +			}
>> +
>> +			snd_rawmidi_status_free(st);
>>  		}
>>  	}
> 
> In my opinion, it's better to split function specific to this purpose
> and call it here. An appropriate name of the function might help readers.

Right. It will make the code cleaner.

-- 
Felipe

[-- Attachment #2: 0x92698E6A.asc --]
[-- Type: application/pgp-keys, Size: 7177 bytes --]

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-08-30 10:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-23 14:09 [PATCH v6 0/2] amidi delay option Felipe F. Tonello
2016-08-23 14:09 ` [PATCH v6 1/2] amidi: add " Felipe F. Tonello
2016-08-29 23:19   ` Takashi Sakamoto
2016-08-30 10:19     ` Felipe Ferreri Tonello
2016-08-23 14:09 ` [PATCH v6 2/2] amidi: use GNU getopt_long() proper argument names Felipe F. Tonello
2016-08-29 23:22   ` Takashi Sakamoto
2016-08-30 10:18     ` Felipe Ferreri Tonello

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.