Skip to content

Commit

Permalink
ALSA: oxfw: Add support AMDTP in-stream
Browse files Browse the repository at this point in the history
Previous commit adds support for some devices which can capture PCM samples.
These devices transmit AMDTP stream in non-blocking mode. This commit adds
functionality to handle AMDTP incoming stream.

OXFW seems to have two quirks:
 - Transmits packets with non-zero dbc in its beginning
 - Transmits packets with wrong values in syt field

For the first quirk, this commit adds CIP_SKIP_INIT_DBC_CHECK flag for
incoming stream to skip first check of dbc.

For the second quirk, this commit doesn't add duplex stream which
Fireworks/BeBoB drivers use. So OXFW driver generates syt value for outgoing
stream.

Here are examples of a sequence of packets transmitted by Behringer F-Control
Audio 202. There are differences between sequences of syt value when OXFW
driver transfers outgoing stream or not.

When driver gives no outgoing stream:
Index   Payload CIP_Header_0    CIP_Header_1
38      14      00020092        900103D1
39      12      00020098        900102FF
40      12      0002009D        9001027F
41      14      000200A2        90010396
42      14      000200A8        900102E8
43      12      000200AE        90010219
44      14      000200B3        90010331
45      12      000200B9        9001025F
46      14      000200BE        90010376
47      12      000200C4        900102A1
00      12      000200C9        9001023E
01      14      000200CE        90010358
02      12      000200D4        90010289
03      16      000200D9        900103A3
04      12      000200E0        900102DD
05      14      000200E5        900103F1
06      12      000200EB        90010335
07      12      000200F0        90010263
08      14      000200F5        9001037C
09      12      000200FB        900102AE

When driver gives outgoing stream:
Index   Payload CIP_Header_0    CIP_Header_1
38      12      000200BD        900104A8
39      14      000200C2        900104A8
40      12      000200C8        900104AC
41      14      000200CD        900104A9
42      12      000200D3        900104B1
43      14      000200D8        900104A8
44      12      000200DE        900104AA
45      14      000200E3        900104A9
46      14      000200E9        900104AE
47      12      000200EF        900104A8
00      14      000200F4        900104AD
01      12      000200FA        900104A7
02      14      000200FF        900104A9
03      12      00020005        900104A9
04      14      0002000A        900104B1
05      12      00020010        900104AA
06      14      00020015        900104AD
07      12      0002001B        900104A7
08      14      00020020        900104AC
09      12      00020026        900104A7

Signed-off-by: Takashi Sakamoto <[email protected]>
Acked-by: Clemens Ladisch <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
takaswie authored and tiwai committed Dec 10, 2014
1 parent ec4dba5 commit b0ac000
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 75 deletions.
6 changes: 3 additions & 3 deletions sound/firewire/oxfw/oxfw-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static int pcm_hw_free(struct snd_pcm_substream *substream)
struct snd_oxfw *oxfw = substream->private_data;

mutex_lock(&oxfw->mutex);
snd_oxfw_stream_stop_simplex(oxfw);
snd_oxfw_stream_stop_simplex(oxfw, &oxfw->rx_stream);
mutex_unlock(&oxfw->mutex);

return snd_pcm_lib_free_vmalloc_buffer(substream);
Expand All @@ -190,8 +190,8 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
int err;

mutex_lock(&oxfw->mutex);
err = snd_oxfw_stream_start_simplex(oxfw, runtime->rate,
runtime->channels);
err = snd_oxfw_stream_start_simplex(oxfw, &oxfw->rx_stream,
runtime->rate, runtime->channels);
mutex_unlock(&oxfw->mutex);
if (err < 0)
goto end;
Expand Down
29 changes: 29 additions & 0 deletions sound/firewire/oxfw/oxfw-proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ static void proc_read_formation(struct snd_info_entry *entry,
formation.rate, formation.pcm, formation.midi);
}

if (!oxfw->has_output)
return;

/* Show output. */
err = snd_oxfw_stream_get_current_formation(oxfw,
AVC_GENERAL_PLUG_DIR_OUT,
&curr);
if (err < 0)
return;

snd_iprintf(buffer, "Output Stream from device:\n");
snd_iprintf(buffer, "\tRate\tPCM\tMIDI\n");
for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) {
format = oxfw->tx_stream_formats[i];
if (format == NULL)
continue;

err = snd_oxfw_stream_parse_format(format, &formation);
if (err < 0)
continue;

if (memcmp(&formation, &curr, sizeof(curr)) == 0)
flag = '*';
else
flag = ' ';

snd_iprintf(buffer, "%c\t%d\t%d\t%d\n", flag,
formation.rate, formation.pcm, formation.midi);
}
}

static void add_node(struct snd_oxfw *oxfw, struct snd_info_entry *root,
Expand Down
Loading

0 comments on commit b0ac000

Please sign in to comment.