Как данные PCM передаются с оборудования на DMA в ALSA и как я могу изменить их перед доступом к пользовательскому простLinux

Ответить Пред. темаСлед. тема
Anonymous
 Как данные PCM передаются с оборудования на DMA в ALSA и как я могу изменить их перед доступом к пользовательскому прост

Сообщение Anonymous »

Я пытаюсь понять, как данные PCM передаются с оборудования на DMA в ALSA при записи. В частности, я хотел бы изменить данные PCM до того, как они будут прочитаны в пользовательском пространстве. Меня интересует изменение данных непосредственно в DMA.
Вот мои вопросы:

Код: Выделить всё

1.What functions are responsible for transferring PCM data from the hardware to DMA in ALSA?
2.Where should I intercept or modify the data in the ALSA driver to achieve this?
3.Are there any recommended functions or hooks within ALSA for modifying PCM data at the DMA       level?
Что я пробовал:
Сначала я попытался изменить функцию __snd_pcm_lib_xfer, но это не дало никакого эффекта. Затем я использовал трассировку-cmd для отслеживания вызовов функций ядра Linux и обнаружил, что функция snd_pcm_update_hw_ptr0 вызывается часто. Я исследовал, как работают old_hw_ptr, new_hw_ptr и hw_base, и пытался их изменить, но это не дало желаемого результата.
Я пытаюсь понять, как пройти данные PCM внутри DMA. Позже я заметил, что функция snd_pcm_set_runtime_buffer вызывается в начале записи, поэтому я добавил журналы printk для проверки деталей буфера DMA.

Код: Выделить всё

static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
struct snd_dma_buffer *bufp)

{
struct snd_pcm_runtime *runtime = substream->runtime;
if (bufp) {
printk(KERN_INFO "Setting DMA buffer for substream: %s\n", substream->name);
printk(KERN_INFO "Buffer area (virtual address): %p\n", bufp->area);
printk(KERN_INFO "Buffer address (physical address): %llx\n", (unsigned long long)bufp->addr);
printk(KERN_INFO "Buffer size: %zu bytes\n", bufp->bytes);

runtime->dma_buffer_p = bufp;
runtime->dma_area = bufp->area;
runtime->dma_addr = bufp->addr;
runtime->dma_bytes = bufp->bytes;
} else {

printk(KERN_INFO "Clearing DMA buffer for substream: %s\n", substream->name);

runtime->dma_buffer_p = NULL;
runtime->dma_area = NULL;
runtime->dma_addr = 0;
runtime->dma_bytes = 0;
}

// 打印运行时最终的 DMA 信息
printk(KERN_INFO "Runtime DMA area: %p\n", runtime->dma_area);
printk(KERN_INFO "Runtime DMA addr: %llx\n", (unsigned long long)runtime->dma_addr);
printk(KERN_INFO "Runtime DMA bytes: %zu\n", runtime->dma_bytes);
}
Вот пример результата, который я получил:

Код: Выделить всё

Setting DMA buffer for substream: subdevice #0
Buffer area (virtual address): 00000000b77507ac
Buffer address (physical address): 0
Buffer size: 356352 bytes
Runtime DMA area: 00000000b77507ac
Runtime DMA addr: 0
Runtime DMA bytes: 356352
Однако теперь я застрял и не знаю, как продолжить изменение или доступ к данным PCM непосредственно в буфере DMA.
Кроме того, я прочитал online, что мне, возможно, придется использовать dmaengine, но я обнаружил, что в моем случае он вообще не вызывался, из-за чего я не понимаю его роли в процессе передачи данных.
От чего Насколько я понимаю, данные PCM сначала сохраняются в буфере DMA, а затем сопоставляются с пользовательским пространством через mmap, а не копируются в пользовательское пространство с помощью copy_to_user (хотя я не совсем уверен). Это заставляет меня задуматься, есть ли способ перехватить данные перед операцией mmap.

Подробнее здесь: https://stackoverflow.com/questions/791 ... i-modify-i
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Linux»