Как стать автором
Обновить

Комментарии 36

В I2S-коммуникации Мастер должен непрерывно, да еще и с правильными клоками, постоянно слать то значение, которое он хочет, чтобы ЦАП удерживал. Без этого, как вы понимаете, вообще ничего работать не будет.

Можно еще короче: "Читайте даташиты, понимайте прочитанное буквально, не лезьте в DSP без понимания, что такое есть звук."

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

Звук, кстати, можно сгенерировать даже через R2R лестничный ЦАП, важно чтобы смена сэмпла происходила на стабильной частоте, да хоть 54321 Гц.

Прошу, не примешивайте то, что к делу не имеет отношения.

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

Открою вам тайну, в названии протокола I²S буква S означает Sound.

Звук, кстати, можно сгенерировать даже через R2R лестничный ЦАП, важно чтобы смена сэмпла происходила на стабильной частоте

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

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

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

Но я вам не скажу за всю Одессу, методов напридумывать можно много.

Именно поэтому, кстати, 44100 = (2*3*5*7)^2

Да уж, какая-то не впечатляющая интрига вышла... Ведь в даташите любого DAC/ADC на I2S будет написано - либо подавайте опорную частоту на CLKIN, либо конфигурируйте чип на автоматическое выделение опорной частоты из BCK.

Это как-то дичь, а не статья.

Читайте даташиты, как уже написали вам.

В I2S-коммуникации Мастер должен непрерывно, да еще и с правильными клоками, постоянно слать то значение, которое он хочет, чтобы ЦАП удерживал. Без этого, как вы понимаете, вообще ничего работать не будет.

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

Hidden text

Внимательно читал даташиты и не сталкивался с такими проблемами :) разве что для mtk пришлось паяться к пяточку что бы мастер клок вытащить, но в целом об этом на этой плате никто не думал, а я чет баловался.

Ну для первой статьи пойдет. Кратко суть проблемы изложена и без меня. В целом да - вопрос о чем писать он такой... К счастью на Хабре уже довольно давно можно полноценно жить не имея за плечами написанных статей. Местами это очень плохо, а местами... Как было в старой рекламе из 90-ых: "Иногда лучше жевать, чем говорить".

Так что с почином. Но продолжать в таком духе наверное не стоит.

Так и я однажды, не дочитав мануал, полез заводить CAN на STMке. Оказалось, что и без трансивера контроллер обидится, и даже с ним линию с другой стороны надо хоть чем-то прикрыть... вроде очевидно, но когда только начинали осваивать микроконтроллеры, то делали вот такие же элементарные ошибки. Благо, у can-а ещё есть регистры ошибок, наглядно показывающие, почему обиделся камень, а Keil со своим драйвером обеспечивает просмотр переменных и регистров в реалтайме, а не только на паузе/по шагам, так что после AVRок отловить и наладить не составило труда.

В I2S-коммуникации Мастер должен непрерывно, да еще и с правильными клоками, постоянно слать то значение, которое он хочет, чтобы ЦАП удерживал. Без этого, как вы понимаете, вообще ничего работать не будет.

что-то я маленько сомневаюсь что это требование надо относить к "I2S-коммуникации". На сколько я понимаю это требование происходит из того что управляемая по I2S микросхема не имеет памяти и поэтому работает по клокам из I2S шины. Теоретически если повесить на ту же I2S шину микросхему с памятью она будет в состоянии "запоминать". Так что это не то что задано I2S, это все таки больше принцип работы конкретной микросхемы, читайте ПДФ-ки на микросхемы очень внимательно!

Нет, это исходит из того что I2S это звук который передаётся с какой-то дискретизацией, 44100, 48000,.. вот эти вот смешные цифры из эпохи mp3, - это частота звукового цифрового потока. и I2S как протокол не подразумевает что эта частота всегда одна и та же, или какого-то соглашения между источником и потребителем о том какой она будет на всё время работы.

Живой пример - вы проигрываете файл mp3 на компьютере mp3 44100, он поступает на DAC как I2S прямо со своей частотой 44100. А потом вы берёте и открываете другой файл, который имеет частоту 48000. Тут возможно было несколько подходов как это могло бы быть сделано:

  • I2S мог иметь что-то типа SPI входа по которому можно было бы "устанавливать" текущую частоту, которую он как вы выражаетесь "запоминал бы". Но это бы означало внедрение во все чипы I2S какой-то рудиментарной микроконтроллерной логики, довольно дорогое решение для дизайна IC. Причём нужно было бы поддерживать эту логику с двух сторон - источник управляемый проигрывателем ставил бы её, а получатель ожидал. Довольно сложная схема.

  • I2S мог бы работать на установленной на старте частоте, и тогда бы любой источник должен был бы перекодировать все проигрываемые файлы к этой частоте, что про конверсиях 48000 -> 44100 давало бы "артефакты", ну просто потому что это не 1:2 и даже не какой-нибудь 11:54, - там очень неочевидная дробь, и заодной вызывала бы сердечный приступ и аудиофилов на форумах одним упоминанием "цифровых артефактов перекодировки" (кстати спойлер, - современные устройства практически не дают артефактов. я использую это в хардварном I2S микшере с несколькими входами и мне не удалось услышать ничего что можно и близко назвать искажениями). и это ещё ладно на компьютере, а как бы страшно усложнялись хардварные проигрыватели, где микросхем общающихся по I2S обычно несколько.

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

I2S мог иметь что-то типа SPI входа по которому можно было бы "устанавливать" текущую частоту, которую он как вы выражаетесь "запоминал бы".

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

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

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

ну так принимающая микросхема должна же как-то понимать текущую частоту входящего потока?

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

Соответственно, период текущей частоты не может быть меньше времени этого удержания, иначе искажения начнутся.

Все как раз таки логично, если клока нет Х времени, нужно перейти в 0, иначе дадим на канал постоянное напряжение которое динамики не любят, да и усилители тоже.

I2S шина синхронная и если вы посмотрите как вообще работают синхронные шины то поймете что там нет такого понятия как "стартовая частота" и вообще каких либо стандартных скоростей. Биты идут по фронту сигнала синхронизации и мы в процессе работы можем менять частоту как угодно. И сигнал синхронизации как бы и есть эта самая опорная частота.

Большое спасибо за статью. И поздравляю с вступлением в сообщество :)

Вам тут некоторые пуристы ставят на вид, что "в документации же всё написано". Однако быстрый ответ на стереотипную проблему, которая из раза в раз встречается у новичков (несмотря на то, что её решение формально есть где-то там в недрах документации) лично я субъективно и претенциозно считаю весьма полезным. Кому-то вы здорово сэкономили время ;)

Пожалуйста, продолжайте в том же духе :)

Спасибо за теплые слова, я понимаю, писал пост на своем опыте и знаю, что не я один такой тугой.

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

Примечательно кстати, что пуризм того или иного комментатора не исключает отсутствие у него компетенций по обсуждаемому вопросу )))

Мой пост не совсем про I2S. Скорее он про пример неясного дизайна, когда модуль работает не так, как ты ожидаешь.

Вся философия IT пронизана инкапсуляцией, когда пользователь не должен знать, что внутри черного ящика. Пользователь должен настроить (инициализировать) ящик, а дальше скармливать или принимать из ящика данные.
Ящик со своей стороны должен делать всё, чтобы с данными обошлись правильно, и они достигли точку назначения в правильном виде, понятном для этой точки назначения.

Я пользователь, хочу увидеть на ЦАП V/2. Готов положить это число в регистр. Жду от модуля, который называет себя I2S, что он сделает всё красиво.

Понятно также, что разрабы STM32 сэкономили на интеграции функционала DMA внутрь I2S, чтобы не множить сущее.

По поводу "read the fkn manual" вспоминаю книгу "Психбольница в руках пациентов", когда боль от взаимодействия с плохим интерфейсом воспринимается в качестве достижения, а не проблемы, которой быть не должно. С этим я, конечно, не согласен.

Вся философия IT пронизана инкапсуляцией, когда пользователь не должен знать, что внутри черного ящика.

На месте пуристов я бы сейчас рассказал, что-то вроде "У нас здесь всё не так как у вас. Не смейте касаться священной электроники своими нечистивыми руками, которыми вы хватались за инкапсуляцию!!11". Что конечно бред и вздор. Но подобное тем не менее периодически излагается. Поэтому не рекомендую оправдываться перед пуристами :)

боль от взаимодействия с плохим интерфейсом воспринимается в качестве достижения, а не проблемы, которой быть не должно

"Не читал, но одобряю" (с). Чувствую, книжка придётся мне по душе )))

Она из девяностых - уже немного устарела. С приходом Эпол некоторые классические разрывы шаблонов уже пофиксены, но не все.

Но подобное тем не менее периодически излагается

Мне кажется, это пошло от тех, кто работал на военку или делал оборудование для жд/метро и прочих чувствительных отраслей с жуткой штукой под названием доказательство безопасности. Там проще сделать своё, нежели доказывать безопасность и отказоустойчивость чего-то готового.

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

Ни в коем случае! Это пошло от людей, которые нахватались по вершкам и дуют щёки от важности.

Видимо мне повезло, ввиду малого опыта работы, с такими пока не сталкиваться

А вот и оно: )))))

Программисты вдруг стали -электронщиками. Прошивку на чем только уже не пишут. Проблема одна только - это плодит псевдо электронщиков. Какие-то компании это устраивает, но часто это мелкие конторы, с мелкими проектами и мелкими бюджетами и маленькой ответственностью. И поверьте мужик который делает конечные автоматы на логике более квалифицирован, чем почитатели "давайте воткнëм МК лампочкой помигать".

Вы взяли аудио-ЦАП. Они гарантированно хорошо воспроизводят звуковые частоты 20Гц-20кГц, но имеют ряд недостатков для других применений. Собственно, за счёт недостатков и получается сделать 16- или более -битный ЦАП таким дешёвым.

  1. Аудио-ЦАП имеет право вообще не пропускать постоянную составляющую сигнала на выход. В звуковом тракте это не нужно, и бывает даже вредно. Но это в описании на конкретный чип надо смотреть. Некоторые DC-составляющую пропускают, некоторые - нет.

  2. Точность выходного напряжения - никакая. У тех аудио-ЦАП и кодеков, с которыми я работал, по описанию повторяемость +-10% даже между двумя стерео-каналами. Для аудио-применений этого достаточно, но для других - не всегда. Тоже можете в описании к вашему чипу проверить.

  3. Это сигма-дельта-ЦАП. Внутренняя структура у него очень простая, напоминает ШИМ. И линейность очень хорошая для аудио. Но чтобы он вообще работал, ему нужна тактовая частота. Причём желательно достаточно чистая, иначе фокуса не получится. И синхронная с данными, а не абы-какая. Потому что на этой частоте работает антиалайзинговый фильтр.

В выбранной Вами СТМке, как я понял, и так есть 2 встроенных ЦАП. Если не нужна большая скорость регулировки напряжения - во всех мк есть ШИМ. Аудио-ЦАП - штука, оптимизированная для конкретной задачи, и натягивание её на другие задачи требует внимательного прочтения описания.

Я пользователь, хочу увидеть на ЦАП V/2. Готов положить это число в регистр. Жду от модуля, который называет себя I2S, что он сделает всё красиво.

Понятно также, что разрабы STM32 сэкономили на интеграции функционала DMA внутрь I2S, чтобы не множить сущее.

То, что предлагается для STM32 из коробки задарма - это просто обёртки для того же вкладывания числа в регистр. Кроме изучения библиотек всё равно приходится также читать доку на чип. Не пользователь Вы. Большинство вещей из так называемого "хардваре абстракшын" нихрена не "абстракшын", и часто даже не получается перенести код между разными семействами STM32F0, F1, F4.

В общем, если хотите не задумываясь сделать типа
echo "42" > /dev/i2s1
это другой уровень программной поддержки, мегабайты стороннего кода и вряд-ли бесплатно. Но говорят, тоже бывает. Слышал, даже на Python как-то люди для мк пишут.

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

Ух ты, надо понимать, как работает протокол, который ты используешь! Полезное знание.

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

обычно микропроцессор гонит данные на цап. Как можно отключить его от цапа?

Ну зависнет МК. Или обновится неудачно. Или сбросится по питанию и будет грузиться десяток секунд.

Понял вас, но у меня вопросов к цапу нет, у меня вопрос к самой периферии.

Пользуясь случаем, задам вопрос. Типичный звуковой тракт состоит из цифрового источника -> цап -> усилителя мощности. Есть ли реализации без промежуточного аналогового преобразования, в которых цифра источника непосредственно задает скважность шима усилителя мощности? Где об этом почитать, по каким ключевым словам искать?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации