1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
From 67dd4d137557909279a21c1b5de87a24c84903f9 Mon Sep 17 00:00:00 2001
From: Giedrius <giedrius@blokas.io>
Date: Tue, 7 Jan 2020 11:04:21 +0200
Subject: [PATCH] Pisound: MIDI communication fixes for scaled down
CPU.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Increased maximum SPI communication speed to avoid running too slow
when the CPU is scaled down and losing MIDI data.
* Keep track of buffer usage in millibytes for higher precision.
Signed-off-by: Giedrius Trainavičius <giedrius@blokas.io>
---
sound/soc/bcm/pisound.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
--- a/sound/soc/bcm/pisound.c
+++ b/sound/soc/bcm/pisound.c
@@ -1,6 +1,6 @@
/*
* Pisound Linux kernel module.
- * Copyright (C) 2016-2019 Vilniaus Blokas UAB, https://blokas.io/pisound
+ * Copyright (C) 2016-2020 Vilniaus Blokas UAB, https://blokas.io/pisound
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -326,7 +326,7 @@ static void spi_transfer(const uint8_t *
transfer.tx_buf = txbuf;
transfer.rx_buf = rxbuf;
transfer.len = len;
- transfer.speed_hz = 100000;
+ transfer.speed_hz = 150000;
transfer.delay_usecs = 10;
spi_message_add_tail(&transfer, &msg);
@@ -403,9 +403,9 @@ static struct spi_device *pisnd_spi_find
static void pisnd_work_handler(struct work_struct *work)
{
enum { TRANSFER_SIZE = 4 };
- enum { PISOUND_OUTPUT_BUFFER_SIZE = 128 };
- enum { MIDI_BYTES_PER_SECOND = 3125 };
- int out_buffer_used = 0;
+ enum { PISOUND_OUTPUT_BUFFER_SIZE_MILLIBYTES = 127 * 1000 };
+ enum { MIDI_MILLIBYTES_PER_JIFFIE = (3125 * 1000) / HZ };
+ int out_buffer_used_millibytes = 0;
unsigned long now;
uint8_t val;
uint8_t txbuf[TRANSFER_SIZE];
@@ -445,7 +445,9 @@ static void pisnd_work_handler(struct wo
had_data = false;
memset(txbuf, 0, sizeof(txbuf));
for (i = 0; i < sizeof(txbuf) &&
- out_buffer_used < PISOUND_OUTPUT_BUFFER_SIZE;
+ ((out_buffer_used_millibytes+1000 <
+ PISOUND_OUTPUT_BUFFER_SIZE_MILLIBYTES) ||
+ g_ledFlashDurationChanged);
i += 2) {
val = 0;
@@ -458,7 +460,7 @@ static void pisnd_work_handler(struct wo
} else if (kfifo_get(&spi_fifo_out, &val)) {
txbuf[i+0] = 0x0f;
txbuf[i+1] = val;
- ++out_buffer_used;
+ out_buffer_used_millibytes += 1000;
}
}
@@ -469,12 +471,14 @@ static void pisnd_work_handler(struct wo
* rate.
*/
now = jiffies;
- out_buffer_used -=
- (MIDI_BYTES_PER_SECOND / HZ) /
- (now - last_transfer_at);
- if (out_buffer_used < 0)
- out_buffer_used = 0;
- last_transfer_at = now;
+ if (now != last_transfer_at) {
+ out_buffer_used_millibytes -=
+ (now - last_transfer_at) *
+ MIDI_MILLIBYTES_PER_JIFFIE;
+ if (out_buffer_used_millibytes < 0)
+ out_buffer_used_millibytes = 0;
+ last_transfer_at = now;
+ }
for (i = 0; i < sizeof(rxbuf); i += 2) {
if (rxbuf[i]) {
@@ -489,6 +493,7 @@ static void pisnd_work_handler(struct wo
|| !kfifo_is_empty(&spi_fifo_out)
|| pisnd_spi_has_more()
|| g_ledFlashDurationChanged
+ || out_buffer_used_millibytes != 0
);
if (!kfifo_is_empty(&spi_fifo_in) && g_recvCallback)
|