Перейти к содержанию
    

Allwinner T113-s3 уделал HiFi4 DSP. Смеяться или плакать?

1 час назад, repstosw сказал:

Стр. 16

image.png.a7c6c2dce84b1bff9cd9d651c8db9a24.png

Но у меня работает.

Возможно, свежая ревизия чипов, уже исправили эту несправедливость.  Потому что частота семплирования 24 кГц более логична, чем 44.1 кГц, и тем более 88.2.

И вообще всё кратное 8 - это хорошо!

 

24кГц это если перделку-свистелку делать... для стандартного аудио 20Гц-20кГц не подходит. 

Частота Найтквиста, теорема Котельникова в помощь...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, vasilius said:

перделку-свистелку

Именно это и создаётся. 

🙂

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, vasilius сказал:

24кГц это если перделку-свистелку делать...

Для голосового канала вполне пойдет, 11кГц на сколь помню там был верх...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

24кГц это если перделку-свистелку делать... для стандартного аудио 20Гц-20кГц не подходит...
Для голосового канала вполне пойдет, 11кГц на сколь помню там был верх...

0.3 .. 3.4 кГц - телефонный канал. Так что 3-кратный оверсэмплинг - оч. хорошо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для речевого сигнала частота семплирования 24 кГц - это шикардос.   Полосы 0..12 кГц хватает, чтобы слышать не "бу-бу-бу...", а вполне идентифицированный голос.

Кодек CELT, мода 24 кбит/c, 50 байтов на сжатый семпл.   Даже музыка удовлетворительно прослушиватся.

 

P.S. В MELP2400 вообще Fs=8 кГц, и ничего, живут с этим. Зато сжатие колоссальное выходит.

P.P.S. А вот всякие потрескивания и попискивания в аудиотракте из-за  мгновенных просадок питающего напряжения и паразитного детектирования ВЧ-полей -  я НЕ прощаю.

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос к гуру олвиннеро-строительства. 

Внешнее прерывание через GPIO. Нужно отлавливать прерывания по фронту и спаду (rising & falling edges).  Сам обработчик прерывания работает исправно.

Вопрос вот в чём: можно ли понять какое именно прерывание произошло:  по фронту или спаду? Не нашёл такого регистра в GPIO.  Может регистр GIC поможет?

 

P.S. Вариант опроса по ножке GPIO_DAT не предлагать - он не работает, когда функция порта выбрана EINT.

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, repstosw сказал:

Может регистр GIC поможет?

Как он может помочь? Его задача отреагировать на сигнал запроса прерывания и все. Это функционал флагов портов, если их нет, то увы и ах...

1 час назад, repstosw сказал:

Вариант опроса по ножке GPIO_DAT не предлагать - он не работает, когда функция порта выбрана EINT.

В обработчике кратковременно снимать статус EINT, читать, потом восстанавливать снова, либо потратить еще одну ногу в параллель и с нее читать... 

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, repstosw said:

P.S. Вариант опроса по ножке GPIO_DAT не предлагать - он не работает, когда функция порта выбрана EINT

И снова здрасьте.

Гляньте у меня. В проекте обслуживается оптический валкодер, прерывания по двум фронтам и получение состояния для грей декодера через чтение DAT работает. Без перепрограсмирований на лету и прочего кошмара.

Для механики решил оставить опрос.

Изменено пользователем GenaSPB

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, GenaSPB сказал:

чтение DAT работает.

Согласен, тоже странным показалось, что не читает...

image.thumb.png.163da4b1cb1c68596a273c8460dd4fb3.png

Единственное, что может запрещать, это сигнал En_in, но тогда он и прерывания запретит.

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, GenaSPB said:

Гляньте у меня. В проекте обслуживается оптический валкодер, прерывания по двум фронтам и получение состояния для грей декодера через чтение DAT работает. Без перепрограсмирований на лету и прочего кошмара.

Попробую. Результат напишу.

 

Подключил микрофон ICS‐43434 к I2S от T113-s3.  В итоге сделал Full-Duplex I2S: одновременно работает микрофон  ICS‐43434 и усилитель MAX98357A. Несмотря на то, что устройства разные, работает идеально.  Используются 2 DMA канала и 4 источника прерывания - Half/Full buffer для микрофона и усилителя. 

Порт I2S  использую один - I2S1. Второй свободен (I2S0).

image.png.06bb2435d09cd8301b00af351c65c0dc.png  image.png.3e83d86efa7c1934c980e4b67b9b1b95.png

У микрофона высокий динамический диапазон:

image.png.51715e7c10a3ca315b505e7a55e68366.png

 

Полностью избавился от аналога.  Теперь не нужно никаких LDO ставить вообще! :sun_bespectacled:

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чисто поворчать: прерывание на половине буфера и полное подсказывают, что речь о zero copy не идёт вообще. Попробуйте double buffer в виде двух закольцованных друг на друга дескрипторов и прерывание по концу пакета. В отработавшем дескрипторе подменять адрес буфера.

Изменено пользователем GenaSPB

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 3/23/2024 at 9:26 AM, GenaSPB said:

прерывание на половине буфера и полное подсказывают, что речь о zero copy не идёт вообще.

Zero copy было в самом начале. Действительно, не нужно ничего никуда копировать процессором , если DMA перебрасывает семплы с микрофона в буфер и сразу же с буфера в УНЧ.

Но впоследствии понадобилось усиление (Digital Gain) + клиппинг ,  и пришлось делать это ручками в обработчике прерывания:

#define SBS (32000/10)

s16 IBuffer[SBS*2] __attribute__ ((aligned (64)));
s16 OBuffer[SBS*2] __attribute__ ((aligned (64)));

#define GAIN 4

s32 DMA_IRQ_Handler(void *arg)
{

#if DMA_I2SI_CHANNEL < 8
                        
 u32 s=DMA_IRQ_PEND_REG0;
 DMA_IRQ_PEND_REG0=s;
                        
#else
                        
 u32 s=DMA_IRQ_PEND_REG1;
 DMA_IRQ_PEND_REG1=s;
                        
#endif

 s32 f;

 static u8 z=0;

 z|=s;

 if(z==0x11)f=0;
 else
 if(z==0x22)f=SBS;
 else       f=-1;

 if(f!=-1)
 {
  cache_inv_range((u32)&IBuffer[f],((u32)&IBuffer[f])+(SBS*sizeof(TYPE)));

  for(int i=0;i<sizeof(OBuffer)/sizeof(s16)/2;i++)OBuffer[f+i]=__SSAT(((s32)IBuffer[f+i])*GAIN,16);

  cache_flush_range((u32)&OBuffer[f],((u32)&OBuffer[f])+(SBS*sizeof(TYPE)));

  z=0;
 }

 UART_putc(s+'0');

 return 0;
}

 

On 3/23/2024 at 9:26 AM, GenaSPB said:

Попробуйте double buffer в виде двух закольцованных друг на друга дескрипторов и прерывание по концу пакета. В отработавшем дескрипторе подменять адрес буфера.

Такое тоже делал, работает.  Мне без разницы какой метод использовать - два дескриптора + full buffer прерывание,  или один дескриптор + два прерывания: half и full buffer.

 

P.S. Вспомнил, в V3s когда буфер был в SRAM - работало только прерывание Full buffer. там и нужны были 2 дескриптора.    С DDR работали оба прерывания(half/full).  И здесь я уже об этом писал несколько лет назад в этой теме...

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос про DMA.

Есть регистр TX_FIFO - он 32-битный, тип IO для DMA (адрес не инкрементируется).

Есть буфер семплов в памяти - они 16-битные   s16 Buffer[N].

 

Если сделать размер семпла I2S  16 бит,  то DMA-транзакции с 16-битным шагом приращения источника и приёмника работают правильно.

Если сделать размер семпла I2S  32 бит,  то DMA-транзакции с 32-битным шагом приращения источника и приёмника работают правильно.

 

Но если сделать размер семпла 32 бита,  а DMA-транзакции с 16-битным шагом приращения источника и приемника, то работает неправильно - я слышу голос с цифровым хрустом, потому что  в TX_FIFO попадает 2 записи с буфера - одна в его младшую часть, другая в старшую.   Проверяется это путём зануления всех четных байт в буфере  семплов.

 

Собственно вопрос: можно ли сделать так, чтобы при копировании DMA, запись с буфера семплов шла только в младшую шасть регистра TX_FIFO, а старшая часть регистра игнорировалась?

image.png.d50ef4a9fa222565f8ded59f1fc2c958.png

Это нужно для того, чтобы сделать I2S семплы 32-битными(или 24-битными),  шина общая.  Микрофон поддерживает 24- и 32-битные семплы,   а усилитель - 16 битные семплы.

Чтобы сэкономить память на усилитель (16-битные семплы), а память на микрофон была 32 битной (для поднятия усиления, младшие биты сдвинутся влево в старншие, без потери точности при усилении).

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще-то в i2s размеп фрейма может быть больше чем используемре кроичкство бит. Попроьбкйте скормить усиоителю больше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

35 minutes ago, GenaSPB said:

Вообще-то в i2s размеп фрейма может быть больше чем используемре кроичкство бит. Попроьбкйте скормить усиоителю больше.

Вообще-то я так и сделал.   Теперь  стоит задача подрезать буфер до 16 бит на семпл, чтобы сэкономить память, при этом сохранив семплы, оставив их 32 битными из-за микрофона.  Важно, не то, что я кормлю усилителю, а то, как это хранится в памяти: я хочу чтобы это были 16-битные семплы без лишнего старшего полу-слова с нулями.

image.png.b1e334f37a56a6e4f7e7f2ba4632678c.png

Увы, I2S не может делать разрядность семпла приёма и передачи разными - только одинаковые.

Я хочу, чтобы семплы для усилителя брались с младших 16 бит TX_FIFO, а с микрофона записывались 32-битные семплы из RX_FIFO.

Таким образом, иметь 16-битный буфер для усилителя и 32-битный буфер с микрофона.

 

MAX98357A в действии.  Вместе с 2-ваттной мини-колонкой 8 Ом:

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...