Commit 6a4e89ff authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: firewire-lib: add a member of frame_multiplier instead of double_pcm_frames

In future commit, interface between data block processing layer and packet
stream processing layer is defined. These two layers communicate the
number of data blocks and the number of PCM frames.

The data block processing layer has a responsibility for calculating the
number of PCM frames. Therefore, 'dual wire' of Dice quirk should be
handled in data block processing layer.

This commit adds a member of 'frame_multiplier'. This member represents
the ratio of the number of PCM frames against the number of data blocks.
Usually, the value of this member is 1, while it's 2 in Dice's 'dual wire'.
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 27ec83b5
...@@ -225,6 +225,16 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s, ...@@ -225,6 +225,16 @@ int amdtp_stream_set_parameters(struct amdtp_stream *s,
s->data_block_quadlets = s->pcm_channels + midi_channels; s->data_block_quadlets = s->pcm_channels + midi_channels;
s->midi_ports = midi_ports; s->midi_ports = midi_ports;
/*
* In IEC 61883-6, one data block represents one event. In ALSA, one
* event equals to one PCM frame. But Dice has a quirk at higher
* sampling rate to transfer two PCM frames in one data block.
*/
if (double_pcm_frames)
s->frame_multiplier = 2;
else
s->frame_multiplier = 1;
s->syt_interval = amdtp_syt_intervals[sfc]; s->syt_interval = amdtp_syt_intervals[sfc];
/* default buffering in the device */ /* default buffering in the device */
...@@ -584,14 +594,6 @@ static void update_pcm_pointers(struct amdtp_stream *s, ...@@ -584,14 +594,6 @@ static void update_pcm_pointers(struct amdtp_stream *s,
{ {
unsigned int ptr; unsigned int ptr;
/*
* In IEC 61883-6, one data block represents one event. In ALSA, one
* event equals to one PCM frame. But Dice has a quirk to transfer
* two PCM frames in one data block.
*/
if (s->double_pcm_frames)
frames *= 2;
ptr = s->pcm_buffer_pointer + frames; ptr = s->pcm_buffer_pointer + frames;
if (ptr >= pcm->runtime->buffer_size) if (ptr >= pcm->runtime->buffer_size)
ptr -= pcm->runtime->buffer_size; ptr -= pcm->runtime->buffer_size;
...@@ -685,7 +687,7 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks, ...@@ -685,7 +687,7 @@ static int handle_out_packet(struct amdtp_stream *s, unsigned int data_blocks,
return -EIO; return -EIO;
if (pcm) if (pcm)
update_pcm_pointers(s, pcm, data_blocks); update_pcm_pointers(s, pcm, data_blocks * s->frame_multiplier);
/* No need to return the number of handled data blocks. */ /* No need to return the number of handled data blocks. */
return 0; return 0;
...@@ -788,7 +790,7 @@ static int handle_in_packet(struct amdtp_stream *s, ...@@ -788,7 +790,7 @@ static int handle_in_packet(struct amdtp_stream *s,
return -EIO; return -EIO;
if (pcm) if (pcm)
update_pcm_pointers(s, pcm, *data_blocks); update_pcm_pointers(s, pcm, *data_blocks * s->frame_multiplier);
return 0; return 0;
} }
......
...@@ -162,11 +162,12 @@ struct amdtp_stream { ...@@ -162,11 +162,12 @@ struct amdtp_stream {
u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM]; u8 pcm_positions[AMDTP_MAX_CHANNELS_FOR_PCM];
u8 midi_position; u8 midi_position;
bool double_pcm_frames;
void (*transfer_samples)(struct amdtp_stream *s, void (*transfer_samples)(struct amdtp_stream *s,
struct snd_pcm_substream *pcm, struct snd_pcm_substream *pcm,
__be32 *buffer, unsigned int frames); __be32 *buffer, unsigned int frames);
unsigned int frame_multiplier;
}; };
int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment