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

Cortex-M7 кол-во циклов на инструкцию

Сваял ASRC, получилось примерно 4 такта на тап или 256тактов на один стерео сэмпл. До нормального DSP

 

Полуофф. А зачем вам ASRC, вы же вроде юсб интерфейс ваяете? Там есть асинхронная синхронизация, даже в видовс нормально работает

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


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

У меня перенос части кода в itcm дал устойчивый прирост быстродействия этой части на 5..10 процентов. А вот с dtcm ощущение, что не работает write back cache, то есть получил почти двухкратное замедление. Асинхронная синхронизация - это когда через выделенный ендпоинт передается желаемый сэмплрэйт? Во первых, расход ендпоинтов. Во вторых, как схема с обратной счязьюг должна быть пред расположена к возбудам. Хотелось бы минимизировать вносимые искажения, собственный ресэмплинг решает задачу. Отвечаю за Шаманъ, так как дел юлаю устройство аналогичного назначения.

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

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


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

А зачем вам ASRC, вы же вроде юсб интерфейс ваяете? Там есть асинхронная синхронизация, даже в видовс нормально работает

Геннадий уже ответил. Асинхронная синхронизация, сведется к какому-нить ASRC алгоритму с неконтролируемыми (с моей стороны) параметрами, только на стороне Windows. Когда ASRC делаю я сам, то я контролирую все параметры сам. К тому же у меня ситуация немного усугубляется тем, что обработка производися отдельным DSP со своим клоком.

 

А вот с dtcm ощущение, что не работает write back cache, то есть получил почти двухкратное замедление.

DTCM некэшируемая память, но очень быстрая, и помнится по 64битной шине к ядру подключена. У меня в разных экспериментах DTCM была самая быстрая. Я кстати кэш и для SRAM1 отключил, получил прирост проиводительности, но это обусловлено особенностями использования SRAM1 у меня и вполне ожидаемо/объяснимо.

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


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

Асинхронная синхронизация - это когда через выделенный ендпоинт передается желаемый сэмплрэйт? Во первых, расход ендпоинтов. Во вторых, как схема с обратной счязьюг должна быть пред расположена к возбудам. Хотелось бы минимизировать вносимые искажения, собственный ресэмплинг решает задачу.

 

 

Асинхронная синхронизация, сведется к какому-нить ASRC алгоритму с неконтролируемыми (с моей стороны) параметрами, только на стороне Windows. Когда ASRC делаю я сам, то я контролирую все параметры сам.

 

Это конечно злостный оффтоп, обсуждать синхронизацию в этом топике. Может модераторы создадут отдельную тему?

Я постоянно слышу мнение о наличии ресемплинга в юсб аудио хостах, но ни разу не смог получить объективного подтверждения этих слухов. Во всех моих тестах, при работающей асинхронной синхронизации кол-во пришедших и ушедших отсчетов в лупбеке всегда совпадало, что на девайсе, что на хосте а также между IN и OUT. Такой необычный ресемплер в виндовзе и маке, что не оставляет никаких следов своей работы. По моему на вегалабе продают асинхронные юсб устройства с возможностью тестирования бит-перфекта. Закольцовывают цифровую часть и считают црц. С ресемплером, где бы он ни находился, тест не сработал бы.

Я подозреваю, что эти слухи исходят от одного мега юсб гуру и я помню один топик здесь на эту тему, переросший в холивар и убитый модератором.

Поэтому, если у вас есть пример, как воспроизвести работу ресемплера, например в виндовс, буду очень благодарен за описание.

Геннадий, я не очень понял фразу о возбудах. Могли бы вы объяснить подробнее?

По поводу ендпоинтов, вы скорее всего правы, виндовс требует выделенного фидбек ендпоинта для работы експлисит режима. Но оба ваших устройства содержат только IN-ы, а как ведет себя в этом случае вин драйвер я не знаю. В лин и мак поддерживается неявная синхронизация, и фидбек ендпоинт просто не нужен.

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


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

Поэтому, если у вас есть пример, как воспроизвести работу ресемплера, например в виндовс, буду очень благодарен за описание.

Геннадий, я не очень понял фразу о возбудах. Могли бы вы объяснить подробнее?

Я про колебания sample rate - оно ведь будет подправляться с запасом? или нет? неизвестно. Процесс будет колеательный... а мне не хотелось бы. Или хоть управлять процессом.

 

Вот дескрипторы моих вариантов аудиоустройств.

Простая тестовая программа, которая читает через mmXXX функции аудиоданные и заворачивает их назад в устройство. Сэмплрейт выставлен номинальный для карты. Все равно, монотонное нарастание очереди/периодическая недостача данных для "воспроизведения" в аудиодеавайсе есть. Кстати, работать оно должно и в случае отсутствия потока в хост.

В дебри вегалаба не вникал, у меня просто отладочная печать состояния очередей буферов в usb device. В статистике работы ресэмплера получаю правдоподобные цифры (порядок совпадает с ожидаемым). У меня ресэмплер простой, выкинуть/добавить отсчет.

Исходник ресэмплера тут https://188.134.5.254/browser/hfreceiver/tr.../buffers.c#L773 сторка 773.

 

upd: если lin и mac при работе в два направления будут синхронизировать - то я просто за... а что делать если только OUT направление активно? И над всем этим решающий голос нехватки ендпоинтов.

96_kHz_descriptor.pdf

192_kHz_descriptor.pdf

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

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


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

Я постоянно слышу мнение о наличии ресемплинга в юсб аудио хостах, но ни разу не смог получить объективного подтверждения этих слухов.

А как без него? Имею наглядный пример - карта E-MU 0202 судя по спектрограммам (на них это очень хорошо видно) периодически выкидываются/добавляются сэмплы. На слух не слышно, но очень хорошо видно. Где это происходит - в карте/ее драйверах/виндоусских драйверах непонятно, но видно, что происходит. Поскольку мой девайс может выводить данные не только "для послушать", то есть необходимость гарантировать неразрывность сигнала и маленький (очень маленький) уровень возникающих искажений.

 

С собственным ASRC я получаю гарантированный результат, заплатить за это 3% производительности и 32кБ памяти я готов :).

 

И над всем этим решающий голос нехватки ендпоинтов.

Да, это тоже важный момент. Мне бы к используемым 5in и 3out EP еще 4 in добавить :)

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


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

Я про колебания sample rate - оно ведь будет подправляться с запасом? или нет? неизвестно. Процесс будет колеательный... а мне не хотелось бы. Или хоть управлять процессом.

Встряну в тред, хоть у меня и не совсем такая ситуация, но тема интересна ;)

Как я понял - у Вас аудиоустройство, принимающее поток сэмплов с USB-хоста и выводящее данные на ЦАП?

Тактирование ЦАП делаете от своего кварца или от потока данных?

Просто насколько я помню - один из стандартных вариантов синхронизации аудиопотока принимаемого с USB и выводимого на аудио-ЦАП - это использовать генератор, подсинхронизируемый данными от USB-хоста. Например: от SOF-маркеров. Дальше - умножитель частоты.

Этот способ вроде описан как один из способов синхронизации в описании USB-стандарта для аудио (хотя не уверен - читал давно).

У меня тоже аудиоустройство, принимающее поток сэмплов и выводящее его на ЦАП. Только сэмплы принимаются не из USB. Но проблема синхронизации есть (как есть в любом устройстве, где есть поток сэмплов между двумя точками с разными не связанными источниками тактирования.

Я сделал ресэмплер с кусочно-линейной аппроксимацией, которому на вход задаётся требуемый коэфф. ресэмплинга - здесь всё очень просто. Сложнее как раз с вычислением этого коэфф. Он у меня вычисляется как произведение двух сомножителей:

а) фиксированного, рассчитываемого при старте, исходя из частоты входящих сэмплов и частоты тактирования ЦАП;

б) переменного, который вычисляется исходя из уровня заполненности кольцевого буфера сэмплов.

Колебаний и возбуждений никаких нет.

 

И почему Вы сделали выкидывание/добавление сэмплов, когда кусочно-линейная аппроксимация лучше и совсем несложна?

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


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

Как я понял - у Вас аудиоустройство, принимающее поток сэмплов с USB-хоста и выводящее данные на ЦАП?

Не совсем - принимается по USB потом отдается DSP процессору по I2S.

 

Тактирование ЦАП делаете от своего кварца или от потока данных?

DSP процессор работает от своего клока, который не перестраиваемый.

 

Я сделал ресэмплер с кусочно-линейной аппроксимацией, которому на вход задаётся требуемый коэфф. ресэмплинга - здесь всё очень просто. Сложнее как раз с вычислением этого коэфф. Он у меня вычисляется как произведение двух сомножителей:

а) фиксированного, рассчитываемого при старте, исходя из частоты входящих сэмплов и частоты тактирования ЦАП;

б) переменного, который вычисляется исходя из уровня заполненности кольцевого буфера сэмплов.

Колебаний и возбуждений никаких нет.

У меня делается Upsampling очень высоко, а потом линейная интерполяция и обратно вниз. В принципе можно сделать небольшой Upsampling (раз в 16) и потом полиномиальную интерполяцию - результат очень схожий. Первый вариант оказалось удобнее реализовать и он побыстрее будет.

 

По поводу вычисления коэффициента - у меня тоже был вначале вопрос, но сегодня поэкспериментировал, вроде все просто получается. Измеряю период SOF пакетов и период синхронизации фреймов I2S относительно клока управляющего процессора (216МГц), потом усредняю. Получается очень неплохо и вычисляется быстро.

 

И почему Вы сделали выкидывание/добавление сэмплов, когда кусочно-линейная аппроксимация лучше и совсем несложна?

Дочитал до этого и понял, что вопрос не ко мне :rolleyes: , но раз уже ответил, то пусть будет :laughing:

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


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

Это конечно злостный оффтоп, обсуждать синхронизацию в этом топике. Может модераторы создадут отдельную тему?

Я постоянно слышу мнение о наличии ресемплинга в юсб аудио хостах, но ни разу не смог получить объективного подтверждения этих слухов.

У меня есть USB Audio устройство на F103 с последующим Class D усилителем TAS5715. Как известно, F103 не может обеспечить точные частоты I2S. В моем случае для 44.1kHz я получаю по документации и факту 43.269kHz. Путем кольцевого буфера с контролем наполнения и feedback endpoint, без ресамплинга в процессоре, я запрашиваю у хоста (win10) фактически требуемую частоту потока.

 

Как там windows чего перекодирует и пересчитывает, не знаю. Факт есть - все работает прилично, но... с заметным на слух(!) замедлением музыкального произведения на, как очевидно, -1.88%. Под заметностью на слух имеется ввиду, что если непостредственно после прослушивания произведения через "мое" устройство, послушать его через колонки от PC, то разница в темпе слышна. Может какой крутой дирижер и без последующего сравнения заметит: читал как-то, что виртуозы дирижерского искусства при записи оркестра в студии произведения часовой длины делают ошибку всего в 2-3 секунды от дубля к дублю.

 

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


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

DSP процессор работает от своего клока, который не перестраиваемый.

Я это и имел в виду.

 

У меня делается Upsampling очень высоко, а потом линейная интерполяция и обратно вниз.

Когда у меня был проект на DSP, то и я так делал: ;)

N-кратное добавление отсчётов, затем - ФНЧ, затем - децимация вниз.

 

Измеряю период SOF пакетов и период синхронизации фреймов I2S относительно клока управляющего процессора (216МГц), потом усредняю. Получается очень неплохо и вычисляется быстро.

Так ведь период измерения небольшой и отношение частоты SOF или I2S к 216МГц - небольшое, так что если частоты отличаются незначительно (из-за погрешности кварцев), то будут получаться всё время константные результаты, с редкими биениями на +-1 ?

Или Вы интегрируете по нескольким измерениям?

 

Дочитал до этого и понял, что вопрос не ко мне :rolleyes: , но раз уже ответил, то пусть будет :laughing:

Не страшно, Ваше мнение тоже интересно ;)

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


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

И почему Вы сделали выкидывание/добавление сэмплов, когда кусочно-линейная аппроксимация лучше и совсем несложна?

Прекрасно!

Есть код, в котором этот алгоритм применен?

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


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

Так ведь период измерения небольшой и отношение частоты SOF или I2S к 216МГц - небольшое, так что если частоты отличаются незначительно (из-за погрешности кварцев), то будут получаться всё время константные результаты, с редкими биениями на +-1 ?

Ну как сказать небольшой - за 1мс можно посчитать 216000тактов, т.е. не вдаваясь в нюансы получается дискретность измерения 1/216000 = 5ppm. Как бы и не плохо, тем более джиттер при таком "программном замере" из-за разных факторов получается прилично больше (порядка +-100тактов).

 

Более правильный/точный метод это задействовать таймер TIM2, но руки пока не еще дошли - надо кое-какие нюансы самого ASRC допилить :).

 

Или Вы интегрируете по нескольким измерениям?

Использую простой ФНЧ первого порядка. Его основная задача уменьшить джиттер, поскольку плавают измерения (получается 216048+-100 тактов, надо переходить на аппаратный замер таймером). Вот картинка - довольно наглядно все демонстрирует:

 

post-39839-1493794309_thumb.png

 

Есть код, в котором этот алгоритм применен?

Я на cqham о подобном говорил. При достаточно большом соотношении частоты дискретизации и максимальной частоты сигнала получается более-менее. Алгоритм очень простой - соедините отсчеты линиями, теперь у Вас есть значения сигнала в произвольной точки времени (что собственно для ASRC и нужно) :) "Возня" с более сложными алгоритмами фактически сводится к более точной интерполяции сигнала между отсчетами.

 

Кода нет, я этот вариант только покрутил в Матлабе и отказался, т.к. при моих соотношениях частоты дискретизации и сигнала (12кГц:3.5кГц) он дает очень много искажений.

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

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


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

Можно ли наплевать на спектральные "прострелы" из-за вставления/убирания сэмпла при соотношении частоты сигнала 3.5 кГц и дискретизации 48 кГц?

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


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

Можно ли наплевать на спектральные "прострелы" из-за вставления/убирания сэмпла при соотношении частоты сигнала 3.5 кГц и дискретизации 48 кГц?

Как по мне, то выглядит не очень - здесь отклонение частоты максимальное для USB FS :( :

post-39839-1493799512_thumb.png

А здесь отклонение частоты максимальное для USB HS:

post-39839-1493799519_thumb.png

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


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

Есть код, в котором этот алгоритм применен?

Да код там простейший:

#define DAC_FS       68000 //[Hz] желаемая частота квантования ЦАП (<=реальной)
#define DAC_DIV (TimerAPBCLK(nTIM_dac, H) / DAC_FS)
#define DAC_FS_REAL divCeil(TimerAPBCLK(nTIM_dac, H), DAC_DIV) //[Hz] реальная частота квантования ЦАП (>=DAC_FS) [Hz]
#define DS_FACTOR  3                      //показатель макс.даунсэмплинга
#define DS_MAX     ((1 << DS_FACTOR) - 1) //макс.даунсэмплинг (макс.возможное отношение частоты сэмплирования mp3-потока к DAC_FS_REAL)
static u32 rsmplX;    //текущая фаза ресэмплинга; целая часть - старшие DS_FACTOR бит
static u32 rsmplFix;  //отношение частоты сэмплирования mp3 к частоте DAC_FS_REAL; целая часть - старшие DS_FACTOR бит
static u32 rsmplVar;  //произведение rsmplFix и переменного коэфф.ресэмплинга, вычисляемого от уровня заполненности inbuf.ring; формат аналогичен rsmplFix
static u16 rsmplBSiz; //кол-во пар (левый/правый) сэмплов в rsmplBuf

static void ReSmpl()
{
 CPU_SR_ALLOCATE();
 uint i0, i1, n, n1 = rsmplBSiz;
 //n1 - число сэмплов во вх.буфере
 s16 *psr = &rsmplBuf[0]; //указатель поток вх.сэмплов (сэмплы хранятся парами 16-битных значений для левого/правого канала)
 while (1) {
   i1 = sbufW; //индекс записи в кольцевой буфер вых.сэмплов
   if ((int)(n = (i0 = sbufE) - i1 - 1) < 0) {
     n = ncell(smplBuf.data) - i1;
     if (!i0) n--;
   }
   //здесь n - число сэмплов ЦАП, которое можно записать в вых.буфер
   if (!n) { //нет места для записи в smplBuf.data
     if (afaza == AFAZA_BREAK) return;
     ENTR_CRT_SECTION();
     if (afaza == AFAZA_PREBUF) {
       i0 = ibufR;
       if ((int)(n = ibufW - i0) < 0) n += sizeof(inbuf.ring);
       if (n >= prebufPorog || aoutOn == OTYP_MEM) {
         afaza = AFAZA_PLAY;
         EXIT_CRT_SECTION();
         TaskChangePrio(PRIO_TASK_AOUT_LOW, PRIO_TASK_AOUT_HIGH);
       } else EXIT_CRT_SECTION();
     } else EXIT_CRT_SECTION();
     MboxPend(mboxOut, ms2tkt(20));
     continue;
   }
   u32 *psw = &smplBuf.data[i1]; //указатель на формируемый поток вых.сэмплов
   u32 c, c0, c1, ca = rsmplX;
   do { //здесь собственно - сам цикл ресэмплинга входных отсчётов в выходные
     n1 -= c = (ca += rsmplVar) >> 32 - DS_FACTOR;
     psr += c * 2;
     ca -= c << 32 - DS_FACTOR;
     c = ca >> 16 - DS_FACTOR;
     c0 = (psr[2] * (s32)c + psr[0] * (s32)(B16 - c) >> 16) * mp3Volume; //здесь собственно вычисление очередного вых. сэмпла для левого канала (а может правого? ;)
     c1 = (psr[3] * (s32)c + psr[1] * (s32)(B16 - c) >> 16) * mp3Volume; //здесь для другого канала 
     *psw++ = (c0 + B23 >> 8 & 0xFFF0) | (c1 + B23 >> 12 << 20);   //объединяем и преобразуем в формат 2-канального ЦАП STM32F429
   } while (--n && n1 > DS_MAX);
   rsmplX = ca;
   i1 = psw - &smplBuf.data[0];
   if (i1 >= ncell(smplBuf.data)) i1 = 0;
   sbufW = i1;
   if (n1 <= DS_MAX) break;
 }
 rsmplBSiz = n1;
 memmove(&rsmplBuf[0], psr, n1 + 1 << 2);
}

DAC_FS - можно задать любым какое нравится и поддерживает ЦАП, но желательно близким к частоте вх.потока и если ниже частоты вх.потока, то не более чем в DS_MAX раз;

rsmplFix - у меня вычисляется для каждого вх. MP3-фрейма - из него берётся samplerate этого фрейма и получаем значение фиксированного коэфф. ресэмплинга для данного MP3-фрейма;

rsmplVar - вычисляется непрерывно - это произведение rsmplFix на коэфф. заполненности основного кольцевого буфера mp3-потока; за счёт этого выполняется согласование скоростей вх.потока (определяемого генератором передатчика) и вых. потока (определяемого тактовой ЦАП); зависимость коэфф. заполненности кольц.буфера - нелинейная.

 

Более правильный/точный метод это задействовать таймер TIM2, но руки пока не еще дошли - надо кое-какие нюансы самого ASRC допилить :).

Использую простой ФНЧ первого порядка. Его основная задача уменьшить джиттер, поскольку плавают измерения (получается 216048+-100 тактов, надо переходить на аппаратный замер таймером).

Имхо - у SOF-фреймов от хоста тоже может быть джиттер. Так что аппаратным или не аппаратным таймером мерять - всё равно значения будут дёргаться - так как погрешность возникает не у Вас. Всё равно придётся усреднять или ФНЧ.

 

Алгоритм очень простой - соедините отсчеты линиями, теперь у Вас есть значения сигнала в произвольной точки времени (что собственно для ASRC и нужно) :) "Возня" с более сложными алгоритмами фактически сводится к более точной интерполяции сигнала между отсчетами.

Кода нет, я этот вариант только покрутил в Матлабе и отказался, т.к. при моих соотношениях частоты дискретизации и сигнала (12кГц:3.5кГц) он дает очень много искажений.

Приведённый мной код должен нормально работать при соотношениях вх./вых. частот сэмплирования (коэфф.ресэмплинга) в диапазоне менее: 0.5<K<2.

Он конечно будет работать и за пределами этого диапазона, но тогда часть сэмплов будет просто выкидываться (не учитываться в вых.сигнале). Чтобы убрать этот недостаток надо по идее поток вх.сэмплов предварительно прогнать через ФНЧ (а для случая K<=0.5 - предварительно добавить сэмплов в поток так, чтобы стало K>0.5 и потом прогнать через ФНЧ). Но я уже не стал этим заморачиваться, так как и такое качество меня уже устроило :rolleyes:

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


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

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

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

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

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

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

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

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

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

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