|
Cortex-M7 кол-во циклов на инструкцию |
|
|
|
 |
Ответов
(45 - 55)
|
May 3 2017, 09:08
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(Genadi Zawidowski @ May 3 2017, 10:42)  Можно ли наплевать на спектральные "прострелы" из-за вставления/убирания сэмпла при соотношении частоты сигнала 3.5 кГц и дискретизации 48 кГц? Извиняюсь, прочитал невнимательно, а разговор был про линейную интерполяцию... Если просто выкидывать, то оно щелкать будет. Вот файл - 10 секунд, 3.5кГц сигнал, 48кГц оцифровка, каждый 24000й сэмпл удален, что соответствует разнице частот 41ppm.
Сообщение отредактировал Шаманъ - May 3 2017, 09:08
Прикрепленные файлы
ASRCr.7z ( 730 байт )
Кол-во скачиваний: 4
|
|
|
|
|
May 3 2017, 11:56
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(jcxz @ May 3 2017, 11:50)  Имхо - у SOF-фреймов от хоста тоже может быть джиттер. Так что аппаратным или не аппаратным таймером мерять - всё равно значения будут дёргаться - так как погрешность возникает не у Вас. Всё равно придётся усреднять или ФНЧ. Да это понятно, но избавиться от дополнительного джиттера (связанного с вызовами прерываний) все же стоит. Переделал на таймер. Не очень удобно оно в STM32 сделано, ну да ладно. С ФНЧ с постоянной времени 0.2с получается теперь так:
В цифрах в среднем джиттер меньше где-то в 1.5..2раза и не зависит от того, что делает девайс - с таймером однозначно лучше. Теперь осталось прикрутить часть со стороны DSP процессора и потом устроить "наведение порядка". Эх, зря я не предусмотрел подачу MCLK на SAI интерфейс от DSP процессора, придется костыли изобретать  ...
|
|
|
|
|
May 3 2017, 13:03
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(jcxz @ May 3 2017, 15:44)  отдавать поток сэмплов как есть, А как отдать его через SAI интерфейс "как есть"? Я ведь его могу затактировать или со стороны DSP, или со стороны управляющего STM32. Оба клока асинхронные относительно клока USB. Придется сделать на STM32 что-то типа FLL, чтобы загнать частоту SAI (в этом случае он будет мастером) в допустимые пределы... В принципе можно и так, боюсь только джиттер у такого решение вылезет большой, скорее всего бОльший, чем если сразу сделать ASRC на STM32 ориентируясь на соотношение частот SAI/USB. Цитата а в DSP делать ресэмплинг на коэфф. равный произведению постоянной и переменной части; переменную часть вычислять от уровня заполненности буфера принимаемых DSP сэмплов; постоянная Вам известна. Тогда и мерить/усреднять ничего не надо - это всё будет делать кольцевой буфер принимаемых сэмплов в DSP. Через отслеживание буфера боюсь нужное качество не получу, или буфер сильно большой придется делать (сейчас дополнительная задержка не превышает 1..2 мс - это 12..24сэмплов).
|
|
|
|
|
May 3 2017, 13:44
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Шаманъ @ May 3 2017, 15:03)  А как отдать его через SAI интерфейс "как есть"? Я ведь его могу затактировать или со стороны DSP, или со стороны управляющего STM32. Оба клока асинхронные относительно клока USB. Ну и пускай. Скорость SAI сделать такой, чтобы точно хватало для передачи потока при любом соотношении частот с небольшим запасом по скорости. Да, конечно, уровень загрузки кольцевого буфера в DSP будет не стоять, а болтаться у некоего значения - ничего страшного. Цитата(Шаманъ @ May 3 2017, 15:03)  Через отслеживание буфера боюсь нужное качество не получу, или буфер сильно большой придется делать (сейчас дополнительная задержка не превышает 1..2 мс - это 12..24сэмплов). Необходимый размер буфера будет зависеть от размера регулярных "биений" скорости потока сэмплов - надо, чтобы он был заведомо больше этих биений. У меня весь буфер разбит на 3 участка: A, B, C. Размерности участков например такие: A - от 0% до 20% заполненности; B - 20%...80%; C - 80%...100% заполненности (конкретные значения могут быть другие). Участок B - горизонтальный: при нахождении уровня заполненности в нём, переменная часть коэфф. ресэмплинга == 1. Участок A - линейно-наклонный: переменная часть коэфф. ресэмплинга изменяется по линейному закону от 1 до 1-D/100 при смещении указателя заполненности от 20% до 0%. Участок C - линейно-наклонный: переменная часть коэфф. ресэмплинга изменяется по линейному закону от 1 до 1+D/100 при смещении указателя заполненности от 80% до 100%. где D - максимальное значение (в %) переменной части коэфф. ресэмплинга (может быть любое значение, например 10%). Размер участка B выбирается таким, чтобы он полностью поглощал регулярные биения загрузки буфера. Это работает так: При старте вначале идёт пребуферизация (сэмплы только накапливаются в буфер, без выходного потока) до некоторого значения на участке B. Потом включается обычный рабочий режим ресэмплинга. В реале, если частоты генераторов источника и ЦАП идеально совпадают, то уровень заполненности устаканится на некотором значении - будет регулярно болтаться вокруг этого значения на суммарную величину всех джиттеров. Если частоты генераторов различаются в ту или иную сторону, то этот уровень загрузки будет постепенно смещаться в сторону участка A или C (тоже с биениями) и в конце-концов - залезет в A или C, где и устаканится на некотором значении (будет болтаться возле него), до тех пор, пока разница частот не изменится (например из-за влияния температур на генераторы) и тогда может поползти в обратную сторону. Вот примерно так это у меня и работает. Как плюс метода - он не требует никаких дополнительных измерений и устойчив к довольно большому и неравномерному джиттеру (у меня поток сэмплов приходит с TCP-сокета работающего поверх WiFi - поток болтается очень даже произвольно).
|
|
|
|
|
May 3 2017, 16:12
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(jcxz @ May 3 2017, 16:44)  Это работает так: Да, у Вас получается вариант регулирования с обратной связью, у меня вариант прямого регулирования. Цитата Если частоты генераторов различаются в ту или иную сторону, то этот уровень загрузки будет постепенно смещаться в сторону участка A или C (тоже с биениями) и в конце-концов - залезет в A или C, где и устаканится на некотором значении (будет болтаться возле него), до тех пор, пока разница частот не изменится (например из-за влияния температур на генераторы) и тогда может поползти в обратную сторону. Т.е. реализован обычный пропорциональный регулятор с ОС и зоной нечувствительности. А почему интегратор не добавили? Логично добавить интегратор, чтобы система стала астатической. Тогда после коррекции буфер возвратится на участок В (может правда интегрирование есть, но я не понял этого из описания). С одной стороны, при высокой долговременной стабильности генераторов зона нечувствительности это плюс, но как только мы начинаем "плыть", она становится минусом, т.к. без нее корректировка начнется раньше и будет проходить "плавнее" = с меньшей модуляцией основного сигнала, а с таким алгоритмом чем быстрее уплывает частота, тем агрессивнее коррекция, что при высокой скорости уплывания опять становится плюсом  . Интересно посмотреть, как это выглядит при объективном контроле - Вы случайно не делали замеров типа спектров, как я выше выкладывал?
|
|
|
|
|
May 4 2017, 08:27
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Шаманъ @ May 3 2017, 18:12)  А почему интегратор не добавили? Логично добавить интегратор, чтобы система стала астатической. Тогда после коррекции буфер возвратится на участок В (может правда интегрирование есть, но я не понял этого из описания). А зачем интегратор? Участки A и C сами по себе являются интеграторами, точнее - их длина. Если нужна большая "интегрируемость", то увеличиваем размер этих участков (они становятся более пологими) и всё. И нет - указатель буфера не должен возвращаться на участок B, если между генераторами есть постоянная разница частот (в несколько ppm например из-за их погрешности). Он должен находиться на участке A или C, на некотором удалении от его границы с B. Величина этого удаления как раз и определяется разностью частот. Если разность частот постоянна - он как раз и будет стабильно находиться в той точке, внося свой дополнительный вклад в произведение коэффициентов ресэмплинга. Ну т.е. в реале из-за джиттера он конечно не находится всё время в одной точке, а колеблется около неё. Нужен больший интервал интегрирования - просто увеличиваем размеры участков A и C, делаем их более пологими, можно вообще размер участка B свести к 0 даже. Можно обойтись вообще без участка B, но у меня характер потока такой, что при старте онлайн-радиостанции выплёвывают сразу бОльший объём траффика чем соответствует битрейту. Т.е. - воспроизведение стартует как бы из прошлого на несколько секунд. Радиостанция таким образом как я понимаю обеспечивает пребуферизацию, чтобы не было провалов воспроизведения. Но размер этой пребуферизации у каждой радиостанции свой и заранее не известен. Поэтому, чтобы у меня сразу при старте воспроизведения, не уходил поток в зону ресэмплинга, я и ввёл участок B. Его размер я выбрал экспериментально - пробовал с разными радиостанциями и постарался чтобы все они при старте своей пребуферизацией не вылезали за пределы участка B. Цитата(Шаманъ @ May 3 2017, 18:12)  С одной стороны, при высокой долговременной стабильности генераторов зона нечувствительности это плюс, но как только мы начинаем "плыть", она становится минусом, т.к. без нее корректировка начнется раньше и будет проходить "плавнее" Эта зона у меня выбрана такой большой именно из-за необходимости пропустить пребуферизацию онлайн-радиостанций. И скоростью потока данных от радиостанции я не могу управлять (WiFi-модуль не предоставляет средств управления потоком, типа окна в TCP-сокете). Цитата(Шаманъ @ May 3 2017, 18:12)  Интересно посмотреть, как это выглядит при объективном контроле - Вы случайно не делали замеров типа спектров, как я выше выкладывал? Нет. Да мне не особо интересно какой там спектр. На слух в сигнале не ощущается каких-то искажений - и ладно, так как только это и нужно.  Вот когда в потоке идут большие провалы (бывает некоторые радиостанции изредка приостанавливают поток на неск. секунд, а может и не радиостанции, а что-нить по WiFi), то указатель буфера смещается на участок A и это слышно сразу искажением звуковых частот и замедлением. А потом, когда эта пробка прочищается - наоборот - происходит выброс большого объёма данных и может улететь на участок C (но не всегда как раз из-за размера участка  .
|
|
|
|
|
May 4 2017, 14:03
|
Знающий
   
Группа: Участник
Сообщений: 758
Регистрация: 27-08-08
Пользователь №: 39 839

|
Цитата(jcxz @ May 4 2017, 11:27)  А зачем интегратор? Если посмотреть на проблему "под другим углом", а именно установить конечную цель/критерий работы алгоритма определения соотношения частот поддержание оптимального заполнения буфера (50%), то без интегратора получится статическая САУ. Т.е. заполненность буфера будет определяться соотношением частот источника/приемника. При наличии интегратора САУ приобретет астатизм первого порядка, т.е. ошибка при наличии статичного расхождения частот будет равна 0. Я вчера поэкспериментировал с этим алгоритмом - работает и как у Вас, и с интегратором. Есть некоторые нюансы, как у любой замкнутой САУ, но то такое. Насчет джиттера - в конечном итоге, как ни крути, хоть с прямым управлением, хоть с ОС все определяет фильтр, которым усредняется коэффициент ресемплинга (что неудивительно - ведь фактически через этот коэффициент осуществляется ЧМ)  Но с прямым замером можно обойтись менее агрессивной фильтрацией, ускорить реакцию системы и уменьшить размер буфера/задержу при одинаковом джиттере, т.к. точность и разрешающая способность единичного замера намного выше. Кроме того данные синхронизации доступны при отключенном аудиоустройстве. Для моего применения все это весьма существенно. Сейчас сделал с замером периодов USB SOF и SAI FS двумя таймерами, потом деление и ФНЧ первого порядка => коэффициент ресэмплинга. Заполняемость буфера "гуляет" от 77 до 81 сэмплов. Учитывая обработку блоками по 4 сэмпла можно сказать, что буфер стоит на месте (как и должно быть)  - можно его раза в четыре меньше сделать. Немного напрягают меня палки на спектре (в сравнении с матлабовской моделью), скорее всего это ошибки округления, ну или я где-то налажал в фильтре  - надо будет поразбираться. А так, вот пример уже вместе с ДСП, с синхронизацией от его клока:
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|