diff options
| -rw-r--r-- | sound/firewire/amdtp.c | 61 | ||||
| -rw-r--r-- | sound/firewire/amdtp.h | 2 |
2 files changed, 57 insertions, 6 deletions
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index ef399cadb8a5..0d580186ef1a 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
| @@ -22,6 +22,12 @@ | |||
| 22 | #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) | 22 | #define TICKS_PER_SECOND (TICKS_PER_CYCLE * CYCLES_PER_SECOND) |
| 23 | 23 | ||
| 24 | /* | 24 | /* |
| 25 | * Nominally 3125 bytes/second, but the MIDI port's clock might be | ||
| 26 | * 1% too slow, and the bus clock 100 ppm too fast. | ||
| 27 | */ | ||
| 28 | #define MIDI_BYTES_PER_SECOND 3093 | ||
| 29 | |||
| 30 | /* | ||
| 25 | * Several devices look only at the first eight data blocks. | 31 | * Several devices look only at the first eight data blocks. |
| 26 | * In any case, this is more than enough for the MIDI data rate. | 32 | * In any case, this is more than enough for the MIDI data rate. |
| 27 | */ | 33 | */ |
| @@ -226,6 +232,14 @@ sfc_found: | |||
| 226 | for (i = 0; i < pcm_channels; i++) | 232 | for (i = 0; i < pcm_channels; i++) |
| 227 | s->pcm_positions[i] = i; | 233 | s->pcm_positions[i] = i; |
| 228 | s->midi_position = s->pcm_channels; | 234 | s->midi_position = s->pcm_channels; |
| 235 | |||
| 236 | /* | ||
| 237 | * We do not know the actual MIDI FIFO size of most devices. Just | ||
| 238 | * assume two bytes, i.e., one byte can be received over the bus while | ||
| 239 | * the previous one is transmitted over MIDI. | ||
| 240 | * (The value here is adjusted for midi_ratelimit_per_packet().) | ||
| 241 | */ | ||
| 242 | s->midi_fifo_limit = rate - MIDI_BYTES_PER_SECOND * s->syt_interval + 1; | ||
| 229 | } | 243 | } |
| 230 | EXPORT_SYMBOL(amdtp_stream_set_parameters); | 244 | EXPORT_SYMBOL(amdtp_stream_set_parameters); |
| 231 | 245 | ||
| @@ -467,6 +481,36 @@ static void amdtp_fill_pcm_silence(struct amdtp_stream *s, | |||
| 467 | } | 481 | } |
| 468 | } | 482 | } |
| 469 | 483 | ||
| 484 | /* | ||
| 485 | * To avoid sending MIDI bytes at too high a rate, assume that the receiving | ||
| 486 | * device has a FIFO, and track how much it is filled. This values increases | ||
| 487 | * by one whenever we send one byte in a packet, but the FIFO empties at | ||
| 488 | * a constant rate independent of our packet rate. One packet has syt_interval | ||
| 489 | * samples, so the number of bytes that empty out of the FIFO, per packet(!), | ||
| 490 | * is MIDI_BYTES_PER_SECOND * syt_interval / sample_rate. To avoid storing | ||
| 491 | * fractional values, the values in midi_fifo_used[] are measured in bytes | ||
| 492 | * multiplied by the sample rate. | ||
| 493 | */ | ||
| 494 | static bool midi_ratelimit_per_packet(struct amdtp_stream *s, unsigned int port) | ||
| 495 | { | ||
| 496 | int used; | ||
| 497 | |||
| 498 | used = s->midi_fifo_used[port]; | ||
| 499 | if (used == 0) /* common shortcut */ | ||
| 500 | return true; | ||
| 501 | |||
| 502 | used -= MIDI_BYTES_PER_SECOND * s->syt_interval; | ||
| 503 | used = max(used, 0); | ||
| 504 | s->midi_fifo_used[port] = used; | ||
| 505 | |||
| 506 | return used < s->midi_fifo_limit; | ||
| 507 | } | ||
| 508 | |||
| 509 | static void midi_rate_use_one_byte(struct amdtp_stream *s, unsigned int port) | ||
| 510 | { | ||
| 511 | s->midi_fifo_used[port] += amdtp_rate_table[s->sfc]; | ||
| 512 | } | ||
| 513 | |||
| 470 | static void amdtp_fill_midi(struct amdtp_stream *s, | 514 | static void amdtp_fill_midi(struct amdtp_stream *s, |
| 471 | __be32 *buffer, unsigned int frames) | 515 | __be32 *buffer, unsigned int frames) |
| 472 | { | 516 | { |
| @@ -474,16 +518,21 @@ static void amdtp_fill_midi(struct amdtp_stream *s, | |||
| 474 | u8 *b; | 518 | u8 *b; |
| 475 | 519 | ||
| 476 | for (f = 0; f < frames; f++) { | 520 | for (f = 0; f < frames; f++) { |
| 477 | buffer[s->midi_position] = 0; | ||
| 478 | b = (u8 *)&buffer[s->midi_position]; | 521 | b = (u8 *)&buffer[s->midi_position]; |
| 479 | 522 | ||
| 480 | port = (s->data_block_counter + f) % 8; | 523 | port = (s->data_block_counter + f) % 8; |
| 481 | if ((f >= MAX_MIDI_RX_BLOCKS) || | 524 | if (f < MAX_MIDI_RX_BLOCKS && |
| 482 | (s->midi[port] == NULL) || | 525 | midi_ratelimit_per_packet(s, port) && |
| 483 | (snd_rawmidi_transmit(s->midi[port], b + 1, 1) <= 0)) | 526 | s->midi[port] != NULL && |
| 484 | b[0] = 0x80; | 527 | snd_rawmidi_transmit(s->midi[port], &b[1], 1) == 1) { |
| 485 | else | 528 | midi_rate_use_one_byte(s, port); |
| 486 | b[0] = 0x81; | 529 | b[0] = 0x81; |
| 530 | } else { | ||
| 531 | b[0] = 0x80; | ||
| 532 | b[1] = 0; | ||
| 533 | } | ||
| 534 | b[2] = 0; | ||
| 535 | b[3] = 0; | ||
| 487 | 536 | ||
| 488 | buffer += s->data_block_quadlets; | 537 | buffer += s->data_block_quadlets; |
| 489 | } | 538 | } |
diff --git a/sound/firewire/amdtp.h b/sound/firewire/amdtp.h index cd4c4dfb3951..8a03a91e728b 100644 --- a/sound/firewire/amdtp.h +++ b/sound/firewire/amdtp.h | |||
| @@ -148,6 +148,8 @@ struct amdtp_stream { | |||
| 148 | bool double_pcm_frames; | 148 | bool double_pcm_frames; |
| 149 | 149 | ||
| 150 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; | 150 | struct snd_rawmidi_substream *midi[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; |
| 151 | int midi_fifo_limit; | ||
| 152 | int midi_fifo_used[AMDTP_MAX_CHANNELS_FOR_MIDI * 8]; | ||
| 151 | 153 | ||
| 152 | /* quirk: fixed interval of dbc between previos/current packets. */ | 154 | /* quirk: fixed interval of dbc between previos/current packets. */ |
| 153 | unsigned int tx_dbc_interval; | 155 | unsigned int tx_dbc_interval; |
