Commit c9f3ac2a authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

ALSA: firewire-lib: code refactoring for generation of data block sequence

This commit dissolves sequence generator in terms of the number of data
blocks per packet.
Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20210522013303.49596-6-o-takashi@sakamocchi.jpSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c79b7158
...@@ -357,26 +357,41 @@ void amdtp_stream_pcm_prepare(struct amdtp_stream *s) ...@@ -357,26 +357,41 @@ void amdtp_stream_pcm_prepare(struct amdtp_stream *s)
} }
EXPORT_SYMBOL(amdtp_stream_pcm_prepare); EXPORT_SYMBOL(amdtp_stream_pcm_prepare);
static unsigned int calculate_data_blocks(unsigned int *data_block_state, static void pool_blocking_data_blocks(struct amdtp_stream *s, struct seq_desc *descs,
bool is_blocking, bool is_no_info, const unsigned int seq_size, unsigned int seq_tail,
unsigned int syt_interval, enum cip_sfc sfc) unsigned int count)
{ {
unsigned int data_blocks; const unsigned int syt_interval = s->syt_interval;
int i;
for (i = 0; i < count; ++i) {
struct seq_desc *desc = descs + seq_tail;
/* Blocking mode. */ if (desc->syt_offset != CIP_SYT_NO_INFO)
if (is_blocking) { desc->data_blocks = syt_interval;
/* This module generate empty packet for 'no data'. */
if (is_no_info)
data_blocks = 0;
else else
data_blocks = syt_interval; desc->data_blocks = 0;
/* Non-blocking mode. */
} else { seq_tail = (seq_tail + 1) % seq_size;
}
}
static void pool_ideal_nonblocking_data_blocks(struct amdtp_stream *s, struct seq_desc *descs,
const unsigned int seq_size, unsigned int seq_tail,
unsigned int count)
{
const enum cip_sfc sfc = s->sfc;
unsigned int state = s->ctx_data.rx.data_block_state;
int i;
for (i = 0; i < count; ++i) {
struct seq_desc *desc = descs + seq_tail;
if (!cip_sfc_is_base_44100(sfc)) { if (!cip_sfc_is_base_44100(sfc)) {
// Sample_rate / 8000 is an integer, and precomputed. // Sample_rate / 8000 is an integer, and precomputed.
data_blocks = *data_block_state; desc->data_blocks = state;
} else { } else {
unsigned int phase = *data_block_state; unsigned int phase = state;
/* /*
* This calculates the number of data blocks per packet so that * This calculates the number of data blocks per packet so that
...@@ -388,18 +403,19 @@ static unsigned int calculate_data_blocks(unsigned int *data_block_state, ...@@ -388,18 +403,19 @@ static unsigned int calculate_data_blocks(unsigned int *data_block_state,
*/ */
if (sfc == CIP_SFC_44100) if (sfc == CIP_SFC_44100)
/* 6 6 5 6 5 6 5 ... */ /* 6 6 5 6 5 6 5 ... */
data_blocks = 5 + ((phase & 1) ^ desc->data_blocks = 5 + ((phase & 1) ^ (phase == 0 || phase >= 40));
(phase == 0 || phase >= 40));
else else
/* 12 11 11 11 11 ... or 23 22 22 22 22 ... */ /* 12 11 11 11 11 ... or 23 22 22 22 22 ... */
data_blocks = 11 * (sfc >> 1) + (phase == 0); desc->data_blocks = 11 * (sfc >> 1) + (phase == 0);
if (++phase >= (80 >> (sfc >> 1))) if (++phase >= (80 >> (sfc >> 1)))
phase = 0; phase = 0;
*data_block_state = phase; state = phase;
} }
seq_tail = (seq_tail + 1) % seq_size;
} }
return data_blocks; s->ctx_data.rx.data_block_state = state;
} }
static unsigned int calculate_syt_offset(unsigned int *last_syt_offset, static unsigned int calculate_syt_offset(unsigned int *last_syt_offset,
...@@ -467,24 +483,15 @@ static void pool_ideal_seq_descs(struct amdtp_stream *s, unsigned int count) ...@@ -467,24 +483,15 @@ static void pool_ideal_seq_descs(struct amdtp_stream *s, unsigned int count)
struct seq_desc *descs = s->ctx_data.rx.seq.descs; struct seq_desc *descs = s->ctx_data.rx.seq.descs;
unsigned int seq_tail = s->ctx_data.rx.seq.tail; unsigned int seq_tail = s->ctx_data.rx.seq.tail;
const unsigned int seq_size = s->ctx_data.rx.seq.size; const unsigned int seq_size = s->ctx_data.rx.seq.size;
const unsigned int syt_interval = s->syt_interval;
const enum cip_sfc sfc = s->sfc;
const bool is_blocking = !!(s->flags & CIP_BLOCKING);
int i;
pool_ideal_syt_offsets(s, descs, seq_size, seq_tail, count); pool_ideal_syt_offsets(s, descs, seq_size, seq_tail, count);
for (i = 0; i < count; ++i) { if (s->flags & CIP_BLOCKING)
struct seq_desc *desc = s->ctx_data.rx.seq.descs + seq_tail; pool_blocking_data_blocks(s, descs, seq_size, seq_tail, count);
else
desc->data_blocks = calculate_data_blocks(&s->ctx_data.rx.data_block_state, pool_ideal_nonblocking_data_blocks(s, descs, seq_size, seq_tail, count);
is_blocking, desc->syt_offset == CIP_SYT_NO_INFO,
syt_interval, sfc);
seq_tail = (seq_tail + 1) % seq_size;
}
s->ctx_data.rx.seq.tail = seq_tail; s->ctx_data.rx.seq.tail = (seq_tail + count) % seq_size;
} }
static void update_pcm_pointers(struct amdtp_stream *s, static void update_pcm_pointers(struct amdtp_stream *s,
......
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