ig_z 0 1 мая, 2017 Опубликовано 1 мая, 2017 · Жалоба Сваял ASRC, получилось примерно 4 такта на тап или 256тактов на один стерео сэмпл. До нормального DSP Полуофф. А зачем вам ASRC, вы же вроде юсб интерфейс ваяете? Там есть асинхронная синхронизация, даже в видовс нормально работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 1 мая, 2017 Опубликовано 1 мая, 2017 (изменено) · Жалоба У меня перенос части кода в itcm дал устойчивый прирост быстродействия этой части на 5..10 процентов. А вот с dtcm ощущение, что не работает write back cache, то есть получил почти двухкратное замедление. Асинхронная синхронизация - это когда через выделенный ендпоинт передается желаемый сэмплрэйт? Во первых, расход ендпоинтов. Во вторых, как схема с обратной счязьюг должна быть пред расположена к возбудам. Хотелось бы минимизировать вносимые искажения, собственный ресэмплинг решает задачу. Отвечаю за Шаманъ, так как дел юлаю устройство аналогичного назначения. Изменено 1 мая, 2017 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 1 мая, 2017 Опубликовано 1 мая, 2017 · Жалоба А зачем вам ASRC, вы же вроде юсб интерфейс ваяете? Там есть асинхронная синхронизация, даже в видовс нормально работает Геннадий уже ответил. Асинхронная синхронизация, сведется к какому-нить ASRC алгоритму с неконтролируемыми (с моей стороны) параметрами, только на стороне Windows. Когда ASRC делаю я сам, то я контролирую все параметры сам. К тому же у меня ситуация немного усугубляется тем, что обработка производися отдельным DSP со своим клоком. А вот с dtcm ощущение, что не работает write back cache, то есть получил почти двухкратное замедление. DTCM некэшируемая память, но очень быстрая, и помнится по 64битной шине к ядру подключена. У меня в разных экспериментах DTCM была самая быстрая. Я кстати кэш и для SRAM1 отключил, получил прирост проиводительности, но это обусловлено особенностями использования SRAM1 у меня и вполне ожидаемо/объяснимо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ig_z 0 1 мая, 2017 Опубликовано 1 мая, 2017 · Жалоба Асинхронная синхронизация - это когда через выделенный ендпоинт передается желаемый сэмплрэйт? Во первых, расход ендпоинтов. Во вторых, как схема с обратной счязьюг должна быть пред расположена к возбудам. Хотелось бы минимизировать вносимые искажения, собственный ресэмплинг решает задачу. Асинхронная синхронизация, сведется к какому-нить ASRC алгоритму с неконтролируемыми (с моей стороны) параметрами, только на стороне Windows. Когда ASRC делаю я сам, то я контролирую все параметры сам. Это конечно злостный оффтоп, обсуждать синхронизацию в этом топике. Может модераторы создадут отдельную тему? Я постоянно слышу мнение о наличии ресемплинга в юсб аудио хостах, но ни разу не смог получить объективного подтверждения этих слухов. Во всех моих тестах, при работающей асинхронной синхронизации кол-во пришедших и ушедших отсчетов в лупбеке всегда совпадало, что на девайсе, что на хосте а также между IN и OUT. Такой необычный ресемплер в виндовзе и маке, что не оставляет никаких следов своей работы. По моему на вегалабе продают асинхронные юсб устройства с возможностью тестирования бит-перфекта. Закольцовывают цифровую часть и считают црц. С ресемплером, где бы он ни находился, тест не сработал бы. Я подозреваю, что эти слухи исходят от одного мега юсб гуру и я помню один топик здесь на эту тему, переросший в холивар и убитый модератором. Поэтому, если у вас есть пример, как воспроизвести работу ресемплера, например в виндовс, буду очень благодарен за описание. Геннадий, я не очень понял фразу о возбудах. Могли бы вы объяснить подробнее? По поводу ендпоинтов, вы скорее всего правы, виндовс требует выделенного фидбек ендпоинта для работы експлисит режима. Но оба ваших устройства содержат только IN-ы, а как ведет себя в этом случае вин драйвер я не знаю. В лин и мак поддерживается неявная синхронизация, и фидбек ендпоинт просто не нужен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 1 мая, 2017 Опубликовано 1 мая, 2017 (изменено) · Жалоба Поэтому, если у вас есть пример, как воспроизвести работу ресемплера, например в виндовс, буду очень благодарен за описание. Геннадий, я не очень понял фразу о возбудах. Могли бы вы объяснить подробнее? Я про колебания 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 Изменено 1 мая, 2017 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 2 мая, 2017 Опубликовано 2 мая, 2017 · Жалоба Я постоянно слышу мнение о наличии ресемплинга в юсб аудио хостах, но ни разу не смог получить объективного подтверждения этих слухов. А как без него? Имею наглядный пример - карта E-MU 0202 судя по спектрограммам (на них это очень хорошо видно) периодически выкидываются/добавляются сэмплы. На слух не слышно, но очень хорошо видно. Где это происходит - в карте/ее драйверах/виндоусских драйверах непонятно, но видно, что происходит. Поскольку мой девайс может выводить данные не только "для послушать", то есть необходимость гарантировать неразрывность сигнала и маленький (очень маленький) уровень возникающих искажений. С собственным ASRC я получаю гарантированный результат, заплатить за это 3% производительности и 32кБ памяти я готов :). И над всем этим решающий голос нехватки ендпоинтов. Да, это тоже важный момент. Мне бы к используемым 5in и 3out EP еще 4 in добавить :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 2 мая, 2017 Опубликовано 2 мая, 2017 · Жалоба Я про колебания sample rate - оно ведь будет подправляться с запасом? или нет? неизвестно. Процесс будет колеательный... а мне не хотелось бы. Или хоть управлять процессом. Встряну в тред, хоть у меня и не совсем такая ситуация, но тема интересна ;) Как я понял - у Вас аудиоустройство, принимающее поток сэмплов с USB-хоста и выводящее данные на ЦАП? Тактирование ЦАП делаете от своего кварца или от потока данных? Просто насколько я помню - один из стандартных вариантов синхронизации аудиопотока принимаемого с USB и выводимого на аудио-ЦАП - это использовать генератор, подсинхронизируемый данными от USB-хоста. Например: от SOF-маркеров. Дальше - умножитель частоты. Этот способ вроде описан как один из способов синхронизации в описании USB-стандарта для аудио (хотя не уверен - читал давно). У меня тоже аудиоустройство, принимающее поток сэмплов и выводящее его на ЦАП. Только сэмплы принимаются не из USB. Но проблема синхронизации есть (как есть в любом устройстве, где есть поток сэмплов между двумя точками с разными не связанными источниками тактирования. Я сделал ресэмплер с кусочно-линейной аппроксимацией, которому на вход задаётся требуемый коэфф. ресэмплинга - здесь всё очень просто. Сложнее как раз с вычислением этого коэфф. Он у меня вычисляется как произведение двух сомножителей: а) фиксированного, рассчитываемого при старте, исходя из частоты входящих сэмплов и частоты тактирования ЦАП; б) переменного, который вычисляется исходя из уровня заполненности кольцевого буфера сэмплов. Колебаний и возбуждений никаких нет. И почему Вы сделали выкидывание/добавление сэмплов, когда кусочно-линейная аппроксимация лучше и совсем несложна? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 2 мая, 2017 Опубликовано 2 мая, 2017 · Жалоба Как я понял - у Вас аудиоустройство, принимающее поток сэмплов с USB-хоста и выводящее данные на ЦАП? Не совсем - принимается по USB потом отдается DSP процессору по I2S. Тактирование ЦАП делаете от своего кварца или от потока данных? DSP процессор работает от своего клока, который не перестраиваемый. Я сделал ресэмплер с кусочно-линейной аппроксимацией, которому на вход задаётся требуемый коэфф. ресэмплинга - здесь всё очень просто. Сложнее как раз с вычислением этого коэфф. Он у меня вычисляется как произведение двух сомножителей: а) фиксированного, рассчитываемого при старте, исходя из частоты входящих сэмплов и частоты тактирования ЦАП; б) переменного, который вычисляется исходя из уровня заполненности кольцевого буфера сэмплов. Колебаний и возбуждений никаких нет. У меня делается Upsampling очень высоко, а потом линейная интерполяция и обратно вниз. В принципе можно сделать небольшой Upsampling (раз в 16) и потом полиномиальную интерполяцию - результат очень схожий. Первый вариант оказалось удобнее реализовать и он побыстрее будет. По поводу вычисления коэффициента - у меня тоже был вначале вопрос, но сегодня поэкспериментировал, вроде все просто получается. Измеряю период SOF пакетов и период синхронизации фреймов I2S относительно клока управляющего процессора (216МГц), потом усредняю. Получается очень неплохо и вычисляется быстро. И почему Вы сделали выкидывание/добавление сэмплов, когда кусочно-линейная аппроксимация лучше и совсем несложна? Дочитал до этого и понял, что вопрос не ко мне :rolleyes: , но раз уже ответил, то пусть будет :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 2 мая, 2017 Опубликовано 2 мая, 2017 · Жалоба Это конечно злостный оффтоп, обсуждать синхронизацию в этом топике. Может модераторы создадут отдельную тему? Я постоянно слышу мнение о наличии ресемплинга в юсб аудио хостах, но ни разу не смог получить объективного подтверждения этих слухов. У меня есть USB Audio устройство на F103 с последующим Class D усилителем TAS5715. Как известно, F103 не может обеспечить точные частоты I2S. В моем случае для 44.1kHz я получаю по документации и факту 43.269kHz. Путем кольцевого буфера с контролем наполнения и feedback endpoint, без ресамплинга в процессоре, я запрашиваю у хоста (win10) фактически требуемую частоту потока. Как там windows чего перекодирует и пересчитывает, не знаю. Факт есть - все работает прилично, но... с заметным на слух(!) замедлением музыкального произведения на, как очевидно, -1.88%. Под заметностью на слух имеется ввиду, что если непостредственно после прослушивания произведения через "мое" устройство, послушать его через колонки от PC, то разница в темпе слышна. Может какой крутой дирижер и без последующего сравнения заметит: читал как-то, что виртуозы дирижерского искусства при записи оркестра в студии произведения часовой длины делают ошибку всего в 2-3 секунды от дубля к дублю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 2 мая, 2017 Опубликовано 2 мая, 2017 · Жалоба DSP процессор работает от своего клока, который не перестраиваемый. Я это и имел в виду. У меня делается Upsampling очень высоко, а потом линейная интерполяция и обратно вниз. Когда у меня был проект на DSP, то и я так делал: ;) N-кратное добавление отсчётов, затем - ФНЧ, затем - децимация вниз. Измеряю период SOF пакетов и период синхронизации фреймов I2S относительно клока управляющего процессора (216МГц), потом усредняю. Получается очень неплохо и вычисляется быстро. Так ведь период измерения небольшой и отношение частоты SOF или I2S к 216МГц - небольшое, так что если частоты отличаются незначительно (из-за погрешности кварцев), то будут получаться всё время константные результаты, с редкими биениями на +-1 ? Или Вы интегрируете по нескольким измерениям? Дочитал до этого и понял, что вопрос не ко мне :rolleyes: , но раз уже ответил, то пусть будет :laughing: Не страшно, Ваше мнение тоже интересно ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 2 мая, 2017 Опубликовано 2 мая, 2017 · Жалоба И почему Вы сделали выкидывание/добавление сэмплов, когда кусочно-линейная аппроксимация лучше и совсем несложна? Прекрасно! Есть код, в котором этот алгоритм применен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 3 мая, 2017 Опубликовано 3 мая, 2017 (изменено) · Жалоба Так ведь период измерения небольшой и отношение частоты SOF или I2S к 216МГц - небольшое, так что если частоты отличаются незначительно (из-за погрешности кварцев), то будут получаться всё время константные результаты, с редкими биениями на +-1 ? Ну как сказать небольшой - за 1мс можно посчитать 216000тактов, т.е. не вдаваясь в нюансы получается дискретность измерения 1/216000 = 5ppm. Как бы и не плохо, тем более джиттер при таком "программном замере" из-за разных факторов получается прилично больше (порядка +-100тактов). Более правильный/точный метод это задействовать таймер TIM2, но руки пока не еще дошли - надо кое-какие нюансы самого ASRC допилить :). Или Вы интегрируете по нескольким измерениям? Использую простой ФНЧ первого порядка. Его основная задача уменьшить джиттер, поскольку плавают измерения (получается 216048+-100 тактов, надо переходить на аппаратный замер таймером). Вот картинка - довольно наглядно все демонстрирует: Есть код, в котором этот алгоритм применен? Я на cqham о подобном говорил. При достаточно большом соотношении частоты дискретизации и максимальной частоты сигнала получается более-менее. Алгоритм очень простой - соедините отсчеты линиями, теперь у Вас есть значения сигнала в произвольной точки времени (что собственно для ASRC и нужно) :) "Возня" с более сложными алгоритмами фактически сводится к более точной интерполяции сигнала между отсчетами. Кода нет, я этот вариант только покрутил в Матлабе и отказался, т.к. при моих соотношениях частоты дискретизации и сигнала (12кГц:3.5кГц) он дает очень много искажений. Изменено 3 мая, 2017 пользователем Шаманъ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 3 мая, 2017 Опубликовано 3 мая, 2017 · Жалоба Можно ли наплевать на спектральные "прострелы" из-за вставления/убирания сэмпла при соотношении частоты сигнала 3.5 кГц и дискретизации 48 кГц? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Шаманъ 0 3 мая, 2017 Опубликовано 3 мая, 2017 · Жалоба Можно ли наплевать на спектральные "прострелы" из-за вставления/убирания сэмпла при соотношении частоты сигнала 3.5 кГц и дискретизации 48 кГц? Как по мне, то выглядит не очень - здесь отклонение частоты максимальное для USB FS :( : А здесь отклонение частоты максимальное для USB HS: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 мая, 2017 Опубликовано 3 мая, 2017 · Жалоба Есть код, в котором этот алгоритм применен? Да код там простейший: #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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться