Reworked driver PCM interface to simplify and unify handling of memory mapped and read-write interleaved modes.
Removed driver copy_user(), copy_kernel() and fill_silence() ops. Removed user space buffer transfer handling mode from playback and capture copy_internal() functions.
This commit is contained in:
parent
db3a9520e7
commit
8a5600638b
@ -1,27 +1,525 @@
|
||||
diff --git a/driver/audio_driver.c b/driver/audio_driver.c
|
||||
index 3d9debd..cc6240e 100644
|
||||
--- a/driver/audio_driver.c
|
||||
+++ b/driver/audio_driver.c
|
||||
@@ -936,6 +936,8 @@
|
||||
chip->dma_playback_offset = 0;
|
||||
chip->dma_playback_buffer = runtime->dma_area;
|
||||
chip->pcm_playback_buffer_size = snd_pcm_lib_buffer_bytes(chip->playback_substream);
|
||||
+ // early startup to fix problem with read-write interleaved mode pre-buffering
|
||||
+ chip->mr_alsa_audio_ops->start_interrupts(chip->ravenna_peer, 1);
|
||||
}
|
||||
else if(substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
@@ -99,24 +99,14 @@
|
||||
static struct alsa_ops *g_mr_alsa_audio_ops;
|
||||
|
||||
|
||||
-static int mr_alsa_audio_pcm_capture_copy( struct snd_pcm_substream *substream,
|
||||
- int channel, snd_pcm_uframes_t pos,
|
||||
- void __user *src,
|
||||
- snd_pcm_uframes_t count);
|
||||
static int mr_alsa_audio_pcm_capture_copy_internal( struct snd_pcm_substream *substream,
|
||||
int channel, uint32_t pos,
|
||||
void __user *src,
|
||||
- snd_pcm_uframes_t count,
|
||||
- bool to_user_space);
|
||||
-static int mr_alsa_audio_pcm_playback_copy( struct snd_pcm_substream *substream,
|
||||
- int channel, snd_pcm_uframes_t pos,
|
||||
- void __user *src,
|
||||
snd_pcm_uframes_t count);
|
||||
static int mr_alsa_audio_pcm_playback_copy_internal( struct snd_pcm_substream *substream,
|
||||
int channel, uint32_t pos,
|
||||
void __user *src,
|
||||
- snd_pcm_uframes_t count,
|
||||
- bool from_user_space);
|
||||
+ snd_pcm_uframes_t count);
|
||||
|
||||
/// "chip" : the main private structure
|
||||
struct mr_alsa_audio_chip
|
||||
@@ -611,6 +601,7 @@
|
||||
chip->mr_alsa_audio_ops->get_interrupts_frame_size(chip->ravenna_peer, &ptp_frame_size);
|
||||
if(direction == 1 && chip->capture_substream != NULL)
|
||||
{
|
||||
index 5a90eca..8023708 100644
|
||||
--- a/driver/manager.c
|
||||
+++ b/driver/manager.c
|
||||
@@ -271,6 +271,10 @@
|
||||
return false;
|
||||
+ unsigned long bytes_to_frame_factor;
|
||||
struct snd_pcm_runtime *runtime = chip->capture_substream->runtime;
|
||||
ring_buffer_size = chip->current_dsd ? MR_ALSA_RINGBUFFER_NB_FRAMES : runtime->period_size * runtime->periods;
|
||||
if (ring_buffer_size > MR_ALSA_RINGBUFFER_NB_FRAMES)
|
||||
@@ -620,22 +611,15 @@
|
||||
}
|
||||
|
||||
/// DMA case
|
||||
- if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ||
|
||||
- runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ||
|
||||
- runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX)
|
||||
- {
|
||||
- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride;
|
||||
-
|
||||
- //printk(KERN_DEBUG "capture copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->capture_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size);
|
||||
- mr_alsa_audio_pcm_capture_copy_internal(chip->capture_substream, runtime->channels/*channel*/,
|
||||
- chip->capture_buffer_pos, chip->dma_capture_buffer + chip->dma_capture_offset/**src*/, ptp_frame_size, false);
|
||||
+ bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride;
|
||||
|
||||
MTAL_DP("MergingRAVENNAAudioDriver::startIO\n");
|
||||
+ if (is_playback && self->m_bIsPlaybackIO)
|
||||
+ return true;
|
||||
+ if (!is_playback && self->m_bIsRecordingIO)
|
||||
+ return true;
|
||||
- chip->dma_capture_offset += ptp_frame_size * bytes_to_frame_factor;
|
||||
- if (chip->dma_capture_offset >= chip->pcm_capture_buffer_size)
|
||||
- {
|
||||
- chip->dma_capture_offset -= chip->pcm_capture_buffer_size;
|
||||
- }
|
||||
- }
|
||||
+ //printk(KERN_DEBUG "capture copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->capture_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size);
|
||||
+ mr_alsa_audio_pcm_capture_copy_internal(chip->capture_substream, runtime->channels/*channel*/,
|
||||
+ chip->capture_buffer_pos, chip->dma_capture_buffer + chip->dma_capture_offset/**src*/, ptp_frame_size);
|
||||
+
|
||||
+ chip->dma_capture_offset += ptp_frame_size * bytes_to_frame_factor;
|
||||
+ if (chip->dma_capture_offset >= chip->pcm_capture_buffer_size)
|
||||
+ chip->dma_capture_offset -= chip->pcm_capture_buffer_size;
|
||||
|
||||
chip->capture_buffer_pos += ptp_frame_size;
|
||||
if(chip->capture_buffer_pos >= ring_buffer_size)
|
||||
@@ -654,6 +638,7 @@
|
||||
}
|
||||
else if(direction == 0 && chip->playback_substream != NULL)
|
||||
{
|
||||
+ unsigned long bytes_to_frame_factor;
|
||||
struct snd_pcm_runtime *runtime = chip->playback_substream->runtime;
|
||||
ring_buffer_size = chip->current_dsd ? MR_ALSA_RINGBUFFER_NB_FRAMES : runtime->period_size * runtime->periods;
|
||||
if (ring_buffer_size > MR_ALSA_RINGBUFFER_NB_FRAMES)
|
||||
@@ -662,23 +647,14 @@
|
||||
return -2;
|
||||
}
|
||||
|
||||
- /// DMA case
|
||||
- if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ||
|
||||
- runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ||
|
||||
- runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX)
|
||||
- {
|
||||
- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride;
|
||||
-
|
||||
- //printk(KERN_DEBUG "playback copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->playback_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size);
|
||||
- mr_alsa_audio_pcm_playback_copy_internal(chip->playback_substream, runtime->channels/*channel*/,
|
||||
- chip->playback_buffer_pos/*pos*/, chip->dma_playback_buffer + chip->dma_playback_offset/*src*/, ptp_frame_size/*count*/, false);
|
||||
-
|
||||
- chip->dma_playback_offset += ptp_frame_size * bytes_to_frame_factor;
|
||||
- if (chip->dma_playback_offset >= chip->pcm_playback_buffer_size)
|
||||
- {
|
||||
- chip->dma_playback_offset -= chip->pcm_playback_buffer_size;
|
||||
- }
|
||||
- }
|
||||
+ bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride;
|
||||
+ //printk(KERN_DEBUG "playback copy pos=%u, dma_pos=%u, count=%u, channels=%d pcm_size=%u\n", chip->playback_buffer_pos, pos, ptp_frame_size, runtime->channels, pcm_buffer_size);
|
||||
+ mr_alsa_audio_pcm_playback_copy_internal(chip->playback_substream, runtime->channels/*channel*/,
|
||||
+ chip->playback_buffer_pos/*pos*/, chip->dma_playback_buffer + chip->dma_playback_offset/*src*/, ptp_frame_size/*count*/);
|
||||
+
|
||||
+ chip->dma_playback_offset += ptp_frame_size * bytes_to_frame_factor;
|
||||
+ if (chip->dma_playback_offset >= chip->pcm_playback_buffer_size)
|
||||
+ chip->dma_playback_offset -= chip->pcm_playback_buffer_size;
|
||||
|
||||
chip->playback_buffer_pos += ptp_frame_size;
|
||||
if (chip->playback_buffer_pos >= ring_buffer_size)
|
||||
@@ -988,18 +964,9 @@
|
||||
if(alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
{
|
||||
/// DMA case
|
||||
- if (alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ||
|
||||
- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ||
|
||||
- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX)
|
||||
- {
|
||||
- struct snd_pcm_runtime *runtime = alsa_sub->runtime;
|
||||
- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride;
|
||||
- offset = chip->dma_playback_offset / bytes_to_frame_factor;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- offset = chip->playback_buffer_pos;
|
||||
- }
|
||||
+ struct snd_pcm_runtime *runtime = alsa_sub->runtime;
|
||||
+ unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride;
|
||||
+ offset = chip->dma_playback_offset / bytes_to_frame_factor;
|
||||
|
||||
/// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment
|
||||
/// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k
|
||||
@@ -1022,19 +989,9 @@
|
||||
}
|
||||
else if(alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
{
|
||||
- /// DMA case
|
||||
- if (alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ||
|
||||
- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ||
|
||||
- alsa_sub->runtime->access == SNDRV_PCM_ACCESS_MMAP_COMPLEX)
|
||||
- {
|
||||
- struct snd_pcm_runtime *runtime = alsa_sub->runtime;
|
||||
- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride;
|
||||
- offset = chip->dma_capture_offset / bytes_to_frame_factor;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- chip->mr_alsa_audio_ops->get_input_jitter_buffer_offset(chip->ravenna_peer, &offset);
|
||||
- }
|
||||
+ struct snd_pcm_runtime *runtime = alsa_sub->runtime;
|
||||
+ unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride;
|
||||
+ offset = chip->dma_capture_offset / bytes_to_frame_factor;
|
||||
|
||||
/// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment
|
||||
/// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k
|
||||
@@ -1166,36 +1123,10 @@
|
||||
};
|
||||
|
||||
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
|
||||
-static int mr_alsa_audio_pcm_capture_copy_user( struct snd_pcm_substream *substream,
|
||||
- int channel, unsigned long pos,
|
||||
- void __user *src,
|
||||
- unsigned long count)
|
||||
- {
|
||||
- struct mr_alsa_audio_chip* chip = snd_pcm_substream_chip(substream);
|
||||
- struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
- bool interleaved = runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ? 1 : 0;
|
||||
- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_capture_stride;
|
||||
- return mr_alsa_audio_pcm_capture_copy(substream, interleaved ? -1 : channel, pos / bytes_to_frame_factor, src, count / bytes_to_frame_factor);
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-static int mr_alsa_audio_pcm_capture_copy( struct snd_pcm_substream *substream,
|
||||
- int channel, snd_pcm_uframes_t pos,
|
||||
- void __user *src,
|
||||
- snd_pcm_uframes_t count)
|
||||
-{
|
||||
- struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream);
|
||||
- uint32_t ravenna_buffer_pos = pos * chip->nb_capture_interrupts_per_period;
|
||||
-
|
||||
- return mr_alsa_audio_pcm_capture_copy_internal(substream, channel, ravenna_buffer_pos, src, count, true);
|
||||
-}
|
||||
-
|
||||
static int mr_alsa_audio_pcm_capture_copy_internal( struct snd_pcm_substream *substream,
|
||||
int channel, uint32_t pos,
|
||||
void __user *src,
|
||||
- snd_pcm_uframes_t count,
|
||||
- bool to_user_space)
|
||||
+ snd_pcm_uframes_t count)
|
||||
{
|
||||
struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
@@ -1204,43 +1135,22 @@
|
||||
unsigned int strideIn = chip->current_alsa_capture_stride;
|
||||
uint32_t ravenna_buffer_pos = pos;
|
||||
|
||||
- // todo DSD capture
|
||||
- //uint32_t dsdrate = mr_alsa_audio_get_dsd_sample_rate(runtime->format, runtime->rate);
|
||||
- //uint32_t dsdmode = (dsdrate > 0? mr_alsa_audio_get_dsd_mode(dsdrate) : 0);
|
||||
-
|
||||
-
|
||||
- /// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment
|
||||
- /// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k
|
||||
- /// so respective ring buffers might have different scale and size
|
||||
- //uint32_t alsa_ring_buffer_nb_frames = MR_ALSA_RINGBUFFER_NB_FRAMES / chip->nb_capture_interrupts_per_period;
|
||||
-
|
||||
- //printk("entering mr_alsa_audio_pcm_capture_copy (channel=%d, count=%lu) (substream name=%s #%d) ...\n", channel, count, substream->name, substream->number);
|
||||
- //printk("Bitwidth = %u, strideIn = %u\n", nb_logical_bits, strideIn);
|
||||
-
|
||||
- //if(snd_BUG_ON(ravenna_buffer_pos >= MR_ALSA_RINGBUFFER_NB_FRAMES))
|
||||
- // ravenna_buffer_pos -= MR_ALSA_RINGBUFFER_NB_FRAMES;
|
||||
-
|
||||
-
|
||||
- //printk("capture_copy: rate = %u, dsdmode = %u, #IRQ per period = %u, count = %lu, pos = %lu, ravenna_buffer_pos = %u\n", (dsdrate > 0? dsdrate : runtime->rate), dsdmode, chip->nb_capture_interrupts_per_period, count, pos, ravenna_buffer_pos);
|
||||
- //printk("capture_copy: rate = %u, #IRQ per period = %u, count = %zu, pos = %u, ravenna_buffer_pos = %u, channels = %u\n", runtime->rate, chip->nb_capture_interrupts_per_period, count, pos, ravenna_buffer_pos, runtime->channels);
|
||||
-
|
||||
-
|
||||
if(interleaved)
|
||||
{
|
||||
switch(nb_logical_bits)
|
||||
{
|
||||
case 16:
|
||||
- MTConvertMappedInt32ToInt16LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space);
|
||||
+ MTConvertMappedInt32ToInt16LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false);
|
||||
break;
|
||||
case 24:
|
||||
{
|
||||
switch(strideIn)
|
||||
{
|
||||
case 3:
|
||||
- MTConvertMappedInt32ToInt24LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space);
|
||||
+ MTConvertMappedInt32ToInt24LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false);
|
||||
break;
|
||||
case 4:
|
||||
- MTConvertMappedInt32ToInt24LE4ByteInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space);
|
||||
+ MTConvertMappedInt32ToInt24LE4ByteInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@@ -1251,7 +1161,7 @@
|
||||
break;
|
||||
}
|
||||
case 32:
|
||||
- MTConvertMappedInt32ToInt32LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, to_user_space);
|
||||
+ MTConvertMappedInt32ToInt32LEInterleave(chip->capture_buffer_channels_map, ravenna_buffer_pos, src, runtime->channels, count, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1263,47 +1173,11 @@
|
||||
return count;
|
||||
}
|
||||
|
||||
-/// This callback is called whenever the alsa application wants to write data
|
||||
-/// We use it here to do all the de-interleaving, format conversion and DSD re-packing
|
||||
-/// The intermediate buffer is actually the alsa (dma) buffer, allocated in hw_params()
|
||||
-/// The incoming data (src) is user land memory pointer, so copy_from_user() must be used for memory copy
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
|
||||
-static int mr_alsa_audio_pcm_playback_copy_user( struct snd_pcm_substream *substream,
|
||||
- int channel, unsigned long pos,
|
||||
- void __user *src,
|
||||
- unsigned long count)
|
||||
-{
|
||||
- struct mr_alsa_audio_chip* chip = snd_pcm_substream_chip(substream);
|
||||
- struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
- unsigned long bytes_to_frame_factor = runtime->channels * chip->current_alsa_playback_stride;
|
||||
- return mr_alsa_audio_pcm_playback_copy(substream, channel, pos / bytes_to_frame_factor, src, count / bytes_to_frame_factor);
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-/// This callback is called whenever the alsa application wants to write data
|
||||
-/// We use it here to do all the de-interleaving, format conversion and DSD re-packing
|
||||
-/// The intermediate buffer is actually the alsa (dma) buffer, allocated in hw_params()
|
||||
-/// The incoming data (src) is user land memory pointer, so copy_from_user() must be used for memory copy
|
||||
-static int mr_alsa_audio_pcm_playback_copy( struct snd_pcm_substream *substream,
|
||||
- int channel, snd_pcm_uframes_t pos,
|
||||
- void __user *src,
|
||||
- snd_pcm_uframes_t count)
|
||||
-{
|
||||
- struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream);
|
||||
- /// Ravenna DSD always uses a rate of 352k with eventual zero padding to maintain a 32 bit alignment
|
||||
- /// while DSD in ALSA uses a continuous 8, 16 or 32 bit aligned stream with at 352k, 176k or 88k
|
||||
- /// so respective ring buffers might have different scale and size
|
||||
- uint32_t ravenna_buffer_pos = pos * chip->nb_playback_interrupts_per_period;
|
||||
-
|
||||
- return mr_alsa_audio_pcm_playback_copy_internal(substream, channel, ravenna_buffer_pos, src, count, true);
|
||||
-}
|
||||
-
|
||||
|
||||
static int mr_alsa_audio_pcm_playback_copy_internal( struct snd_pcm_substream *substream,
|
||||
int channel, uint32_t pos,
|
||||
void __user *src,
|
||||
- snd_pcm_uframes_t count,
|
||||
- bool from_user_space)
|
||||
+ snd_pcm_uframes_t count)
|
||||
{
|
||||
struct mr_alsa_audio_chip *chip = snd_pcm_substream_chip(substream);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
@@ -1316,8 +1190,6 @@
|
||||
uint32_t dsdmode = (dsdrate > 0? mr_alsa_audio_get_dsd_mode(dsdrate) : 0);
|
||||
uint32_t ravenna_buffer_pos = pos;
|
||||
|
||||
- //printk("playback_copy: rate = %u, dsdmode = %u, #IRQ per period = %u, count = %u, pos = %lu, ravenna_buffer_pos = %u, alsa_pb_sac = %llu, ravenna_pb_sac = %llu\n", (dsdrate > 0? dsdrate : runtime->rate), dsdmode, chip->nb_playback_interrupts_per_period, count, pos, ravenna_buffer_pos, chip->playback_buffer_alsa_sac, chip->playback_buffer_rav_sac);
|
||||
-
|
||||
if(interleaved)
|
||||
{
|
||||
/// de-interleaving
|
||||
@@ -1325,145 +1197,70 @@
|
||||
unsigned int stepIn = runtime->channels * strideIn;
|
||||
unsigned int stepOut = strideOut * chip->nb_playback_interrupts_per_period;
|
||||
uint32_t ring_buffer_size = MR_ALSA_RINGBUFFER_NB_FRAMES * strideOut;
|
||||
- //printk("playback_copy: de-interleaving %u frames, pos = %llu, ravenna_buffer_pos = %u, with strideIn = %u, strideOut = %u, stepIn = %u, stepOut = %u, ravBuffer_csize = %u \n", count, pos, ravenna_buffer_pos, strideIn, strideOut, stepIn, stepOut, (unsigned int)ravBuffer_csize);
|
||||
|
||||
- if (from_user_space)
|
||||
+ for (chn = 0; chn < runtime->channels; ++chn)
|
||||
{
|
||||
- for (chn = 0; chn < runtime->channels; ++chn)
|
||||
+ uint32_t currentOutPos = ravenna_buffer_pos * strideOut;
|
||||
+ snd_pcm_uframes_t frmCnt = 0;
|
||||
+ in = (unsigned char*)src + chn * strideIn;
|
||||
+ out = chip->playback_buffer + chn * ring_buffer_size + currentOutPos;
|
||||
+ //
|
||||
+ ///Conversion to Signed integer 32 bit LE
|
||||
+ for (frmCnt = 0; frmCnt < count; ++frmCnt)
|
||||
{
|
||||
- uint32_t currentOutPos = ravenna_buffer_pos * strideOut;
|
||||
- snd_pcm_uframes_t frmCnt = 0;
|
||||
- in = (unsigned char*)src + chn * strideIn;
|
||||
- out = chip->playback_buffer + chn * ring_buffer_size + currentOutPos;
|
||||
- //
|
||||
- ///Conversion to Signed integer 32 bit LE
|
||||
- for (frmCnt = 0; frmCnt < count; ++frmCnt)
|
||||
+ /// assumes Little Endian
|
||||
+ if (dsdmode == 0)
|
||||
{
|
||||
- /// assumes Little Endian
|
||||
- int32_t val = 0;
|
||||
- if (dsdmode == 0)
|
||||
- {
|
||||
- switch (nb_logical_bits)
|
||||
- {
|
||||
- case 16:
|
||||
- __get_user(((unsigned char*)&val)[3], &in[1]);
|
||||
- __get_user(((unsigned char*)&val)[2], &in[0]);
|
||||
- break;
|
||||
- case 24:
|
||||
- __get_user(((unsigned char*)&val)[3], &in[2]);
|
||||
- __get_user(((unsigned char*)&val)[2], &in[1]);
|
||||
- __get_user(((unsigned char*)&val)[1], &in[0]);
|
||||
- break;
|
||||
- case 32:
|
||||
- __get_user(val, (int32_t*)in);
|
||||
- break;
|
||||
- }
|
||||
- *((int32_t*)out) = val;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- /// interleaved DSD stream to non interleaved 32 bit aligned blocks with 1/2/4 DSD bytes per 32 bit
|
||||
- uint32_t out_cnt;
|
||||
- for (out_cnt = 0; out_cnt < chip->nb_playback_interrupts_per_period; ++out_cnt)
|
||||
- {
|
||||
- switch (dsdmode)
|
||||
- {
|
||||
- case 1: ///DSD64
|
||||
- __get_user(((unsigned char*)&val)[0], &in[out_cnt]);
|
||||
- break;
|
||||
- case 2: ///DSD128
|
||||
- __get_user(((unsigned char*)&val)[1], &in[2 * out_cnt + 1]);
|
||||
- __get_user(((unsigned char*)&val)[0], &in[2 * out_cnt]);
|
||||
- break;
|
||||
- case 4: ///DSD256
|
||||
- __get_user(val, (int32_t*)in);
|
||||
- break;
|
||||
- }
|
||||
- ((int32_t*)out)[out_cnt] = val;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- in += stepIn;
|
||||
- if (currentOutPos + stepOut >= ring_buffer_size)
|
||||
+ switch (nb_logical_bits)
|
||||
{
|
||||
- currentOutPos = 0;
|
||||
- out = chip->playback_buffer + chn * ring_buffer_size;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- currentOutPos += stepOut;
|
||||
- out += stepOut;
|
||||
+ case 16:
|
||||
+ out[3] = in[1];
|
||||
+ out[2] = in[0];
|
||||
+ out[1] = 0;
|
||||
+ out[0] = 0;
|
||||
+ break;
|
||||
+ case 24:
|
||||
+ out[3] = in[2];
|
||||
+ out[2] = in[1];
|
||||
+ out[1] = in[0];
|
||||
+ out[0] = 0;
|
||||
+ break;
|
||||
+ case 32:
|
||||
+ *(int32_t*)out = *(int32_t*)in;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- for (chn = 0; chn < runtime->channels; ++chn)
|
||||
- {
|
||||
- uint32_t currentOutPos = ravenna_buffer_pos * strideOut;
|
||||
- snd_pcm_uframes_t frmCnt = 0;
|
||||
- in = (unsigned char*)src + chn * strideIn;
|
||||
- out = chip->playback_buffer + chn * ring_buffer_size + currentOutPos;
|
||||
- //
|
||||
- ///Conversion to Signed integer 32 bit LE
|
||||
- for (frmCnt = 0; frmCnt < count; ++frmCnt)
|
||||
+ else
|
||||
{
|
||||
- /// assumes Little Endian
|
||||
- int32_t val = 0;
|
||||
- if (dsdmode == 0)
|
||||
+ /// interleaved DSD stream to non interleaved 32 bit aligned blocks with 1/2/4 DSD bytes per 32 bit
|
||||
+ uint32_t out_cnt;
|
||||
+ for (out_cnt = 0; out_cnt < chip->nb_playback_interrupts_per_period; ++out_cnt)
|
||||
{
|
||||
- switch (nb_logical_bits)
|
||||
+ switch (dsdmode)
|
||||
{
|
||||
- case 16:
|
||||
-
|
||||
- ((unsigned char*)&val)[3] = in[1];
|
||||
- ((unsigned char*)&val)[2] = in[0];
|
||||
+ case 1: ///DSD64
|
||||
+ ((int32_t*)out)[out_cnt] = *(int32_t*)(in + out_cnt) & 0xFF;
|
||||
break;
|
||||
- case 24:
|
||||
- ((unsigned char*)&val)[3] = in[2];
|
||||
- ((unsigned char*)&val)[2] = in[1];
|
||||
- ((unsigned char*)&val)[1] = in[0];
|
||||
+ case 2: ///DSD128
|
||||
+ ((int32_t*)out)[out_cnt] = (((int32_t)(in[2 * out_cnt + 1]) << 8) | ((int32_t)(in[2 * out_cnt]))) & 0xFFFF;
|
||||
break;
|
||||
- case 32:
|
||||
- val = *(int32_t*)(in);
|
||||
+ case 4: ///DSD256
|
||||
+ ((int32_t*)out)[out_cnt] = *(int32_t*)(in);
|
||||
break;
|
||||
}
|
||||
- *((int32_t*)out) = val;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- /// interleaved DSD stream to non interleaved 32 bit aligned blocks with 1/2/4 DSD bytes per 32 bit
|
||||
- uint32_t out_cnt;
|
||||
- for (out_cnt = 0; out_cnt < chip->nb_playback_interrupts_per_period; ++out_cnt)
|
||||
- {
|
||||
- switch (dsdmode)
|
||||
- {
|
||||
- case 1: ///DSD64
|
||||
- val = *(int32_t*)(in + out_cnt) & 0xFF;
|
||||
- break;
|
||||
- case 2: ///DSD128
|
||||
- val = (((int32_t)(in[2 * out_cnt + 1]) << 8) | ((int32_t)(in[2 * out_cnt]))) & 0xFFFF;
|
||||
- break;
|
||||
- case 4: ///DSD256
|
||||
- val = *(int32_t*)(in);
|
||||
- break;
|
||||
- }
|
||||
- ((int32_t*)out)[out_cnt] = val;
|
||||
- }
|
||||
}
|
||||
+ }
|
||||
|
||||
- in += stepIn;
|
||||
- if (currentOutPos + stepOut >= ring_buffer_size)
|
||||
- {
|
||||
- currentOutPos = 0;
|
||||
- out = chip->playback_buffer + chn * ring_buffer_size;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- currentOutPos += stepOut;
|
||||
- out += stepOut;
|
||||
- }
|
||||
+ in += stepIn;
|
||||
+ if (currentOutPos + stepOut >= ring_buffer_size)
|
||||
+ {
|
||||
+ currentOutPos = 0;
|
||||
+ out = chip->playback_buffer + chn * ring_buffer_size;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ currentOutPos += stepOut;
|
||||
+ out += stepOut;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2042,11 +1839,6 @@
|
||||
.prepare = mr_alsa_audio_pcm_prepare,
|
||||
.trigger = mr_alsa_audio_pcm_trigger,
|
||||
.pointer = mr_alsa_audio_pcm_pointer,
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
|
||||
- .copy_user = mr_alsa_audio_pcm_playback_copy_user,
|
||||
-#else
|
||||
- .copy = mr_alsa_audio_pcm_playback_copy,
|
||||
-#endif
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
|
||||
@@ -2060,13 +1852,6 @@
|
||||
.prepare = mr_alsa_audio_pcm_prepare,
|
||||
.trigger = mr_alsa_audio_pcm_trigger,
|
||||
.pointer = mr_alsa_audio_pcm_pointer,
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0)
|
||||
- .copy_user = mr_alsa_audio_pcm_capture_copy_user,
|
||||
- .fill_silence = NULL,
|
||||
-#else
|
||||
- .copy = mr_alsa_audio_pcm_capture_copy,
|
||||
- .silence = NULL, //mr_alsa_audio_pcm_silence,
|
||||
-#endif
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
};
|
||||
|
||||
if (!is_playback) {
|
||||
printk(KERN_DEBUG "starting capture I/O\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user