USB микрофон на ATmega8 и V-USB. Беглый экскурс и рабочая железка

AVR
Как то давно я обещал статейку про реализацию USB микрофона на библиотеке V-USB. Время шло, а статья, как и само устройство не хотели приобретать конечную форму. То время нет, то желание, то возможности. Но на днях выдались пару вечеров (плавно перетекающих в ночь), и работа «пошла». В статье не густо фоток и всеми любимого видео, но зато я постарался раскрыть некоторые возможности библиотеки и пройтись по спецификации USB. Не претендую на большую публику (так как реализовать это можно за 5 секунд на аппаратном USB), но раз обещал…

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

Сразу оговорюсь, что я (как собственно и раньше) не претендую на звание «Учитель года», поэтому буду излагать материал как умею. Не все моменты получится раскрыть в статье, потому как разбирался в этом направлении самостоятельно, многое читал между строк, часть информации является специфичной и узкопрофильной, а часть попросту не понял сам. Примеров на русском я не видел, а вся документация вроде на «вражеском». Так что не судите строго и сами не будите строго ОСУЖДЕНЫ =)

Итак, следует отметить, что USB очень хорошо подходит для передачи звука. Пропускная способность канала USB позволяет передавать не только простой звук, но и высококачественные аудиоданные. Для изготовления USB аудиоустройств также важно и то, что механизм передачи аудиоданных хорошо определен и стандартизирован в спецификации USB. Стандартизированный механизм передачи аудиоданных также позволяет использовать стандартные драйвера (насколько это возможно).

Отдельного внимания требует синхронизация потока данных. Действительно, даже небольшие артефакты в звуковом потоке легко различимы человеческим ухом. Поэтому была разработана и внедрена в стандарт USB надежная схема синхронизации в изохронных передачах (тавтология слегка). Для надежной передачи аудиоданных по шине USB определен класс Audio Device Class, который придерживается данной схемы синхронизации.

Теперь посмотрим, что из себя представляет эта самая изохронная передача данных (в данном случае изохронная конечная точка). Итак, изохронный канал позволяет доставлять пакеты данных без гарантии доставки и без ответов/подтверждений, но зато гарантирует скорость доставки (!!!) в N пакетов за один период шины (1 кГц у low-speed и 8 кГц у high-speed). Именно из-за гарантированной скорости доставки, для передачи потока аудио (видео) используется изохронная передача.

Так, со способом передачи данных по шине определились – изохронная передача данных. Но в изохронной передаче есть несколько типов синхронизации данных. И так, первый тип – асинхронная изохронная передача. В такой передаче конечная точка принимает или передает данные с частотой, являющейся внешней для USB, или с частотой, заданной самим устройством. Второй тип передачи – синхронная изохронная передача. Системная частота для таких конечных точек может контролироваться через SOF (передача StartOfFrame) синхронизацию. Таким образом, конечная точка подстраивает свою частоту под 1 миллисекундный SOF тик или контролирует генерацию SOF и его тактовая частота привязывается к SOF. Также есть адаптивный тип синхронизации. Адаптивная изохронная конечная точка может принимать или передавать данные с любой частотой в своих рабочих пределах. Такие конечные точки должны реализовывать внутри себя процесс (функцию), которая позволяет ей подстраивать свою тактовую частоту под тактовую частоту, которая предлагается ее интерфейсу. Из всех типов синхронизации, самым простым является асинхронный.

Со способом передачи данных и видом синхронизации определились – асинхронная изохронная передача. Теперь пришло время рассмотреть основные составляющие USB аудио устройства. Для управления свойствами аудио функции (устройства), ее составные компоненты можно разделить на основные управляемые составляющие. Их две: юниты (Units) и терминалы (Terminals). Юниты представляют собой базовые составляющие блоки для полного описания большинства аудио функций. Аудио функции строятся соединением нескольких таких юнитов. Каждый юнит имеет минимум один входной пин (вход) и только один выходной. В дополнение к юнитам, которые можно считать проходными элементами для аудио данных, существуют и так называемые терминалы. Бывают входной терминал и выходной. Терминал можно представить себе как конечное звено в аудио функции. Так, АЦП для микрофона является входным терминалом, а конечная точка – выходным. Для колонок конечная точка является входным терминалам, а ЦАП – выходным. Примером юнита может служить блок обработки звука или регулировки громкости и т.д.

Так, для построения простого USB микрофона можно нарисовать следующий рисунок (1):



Немного поясню содержимое данного рисунка. По логике работы микрофона: снятие и оцифровка звука (можно с его обработкой) занимается функционально-законченный блок, а передачей (транспортировкой) этих данных занимается другой блок. Эти блоки в стандарте USB называются интерфейсами. Соответственно их названия довольно логичны: AudioControl и AudioStreaming интерфейсы. Для ввода данных в наше устройство служит входной терминал (IT), который можно представить себе как микрофон + фильтр + АЦП. Поскольку оцифрованный звук нами не обрабатывается, то данные непосредственно передаются на выходной терминал (OT), который представлен конечной точкой. Входной и выходной терминалы в данном случае представляют собой аудио функцию (логически законченная структура терминалов и юнитов, реализующих законченный функциональный блок). В нашем устройстве функция только одна, значит AudioControl Interface состоит только из одной функции. AudioStraming Interface представлен конечной точкой.

Теперь поверхностно рассмотрим рабочую модель Audio Device Class. Устройство может поддерживать несколько конфигураций. В рамках каждой конфигурации может быть несколько интерфейсов, каждый из которых может содержать несколько альтернативных настроек и конечных точек. Для иллюстрации всего вышесказанного, представлю следующий рисунок 2.



Теперь пройдемся немного дальше. В стандарте USB любое устройство представляется хосту как набор дескрипторов, которые описывают вид устройства, его свойства и назначение, его параметры, характеристики, требования, способ обмена информацией и т.д. Из рисунка 2 видна общая структура устройства USB. Каждый из представленных блоков на рисунке описывается своим собственным дескриптором. Для разных классов устройств (CDC, MSD, HID, AUDIO и проч.) в состав стандартных дескрипторов могут входить специфичные для класса дескрипторы. Все они описываются в соответствующих документах спецификации классов устройств.
Немного сумбурно, но теперь попробуем представить себе иерархию дескрипторов для нашего устройства, основываясь на рисунках 1 и 2. Эта иерархия представлена в спецификации на AUDIO DEVICE CLASS, но логика построения прослеживается из приведенного выше материала.



Расписывать в статье каждый из дескрипторов с его параметрами только захламит мой поток мыслей. Если кто будет просматривать код или повторять конструкцию, те просмотрят комментарии и разберутся. На крайняк есть комментарии и всегда можно задать вопрос.
Подробнее остановлюсь на моменте с альтернативными установками. Как видно из рисунка 3, их два. Назначение их может ввести новичков в смятение, но не все так сложно. Как мы помним, для передачи звука мы используем изохронную передачу, которая резервирует определенную полосу пропускания канала USB. Микрофон, подключенный к шине, используется не постоянно, а лишь по мере необходимости. Поэтому альтернативная установка 0 не имеет конечной точки. В случае, когда никто (в смысле программ) не использует микрофон, драйвер, в целях рационального использования ресурсов USB, переключит AudioControl интерфейс на эту установку. Это приведет к тому, что микрофон (AudioControl интерфейс) не будет использовать ресурс шины. При необходимости использования микрофона, драйвер укажет устройству о необходимости использования альтернативной установки 1, которая имеет изохронную конечную точку. Та, в свою очередь, начнет передавать поток аудио данных хосту.
Теперь о V-USB. Большая часть функционала этой библиотеки скрыта от глаз пользователя. В идеале (или насколько я знаю), изохронная передача (как и bulk) передачи не поддерживаются. Но мы обходим это ограничение так, как будто наши конечные точки являются interrupt точками. Со стороны хоста разницы не заметно=) И по поводу переключения альтернативных настроек. Происходит это по команде USBRQ_SET_INTERFACE. Поэтому пришлось немного допилить код драйвера V-USB в функции usbDriverSetup и добавить функцию usbGetAltInterface.
Со схемой сильно не заморачивался и использовал схему из моей прошлой статьи. Сигнал подается на вход ADC0. Сигнал с микрофона нужно усилить и ограничить его спектр в соответствии с выбранной частотой дискретизации (в моем случае это 8kHz). Как это сделать можно прочитать в статье товарища Lifelover.



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



P/S: Надеюсь статья пригодиться хоть кому-нибудь, ну или по крайней мере была полезной или интересной. Спасибо за внимание!
  • +7
  • 01 февраля 2012, 01:14
  • lleeloo
  • 2
Файлы в топике: Microphone.Mega8.libusb.zip, sample(8bit8khz).mp3

Комментарии (42)

RSS свернуть / развернуть
Прослушал звуковой файл, мне показалось, что часть пакетов или не успевает прибывать вовремя или вообще теряется по дороге. Искажения похожи на те, которые наблюдаются при прохождении аудиосигнала по каналу Bluetooth при плохом радиосигнале. Наверное надо еще пошаманить с софтовой USB частью, то ли в контролере то ли в компьютере.
И еще, хотелось бы поднять качество оцифровки до 11025 Гц и вытянуть все 10 бит разрядности АЦП.
0
  • avatar
  • Aneg
  • 01 февраля 2012, 03:07
11025 Hz по 16(10)бит получим ~22 KB/s, что для V-USB это перебор =( По поводу качества — хз. Динамический диапазон мог превысить, да и фильтра не ставил. Просто проверил работоспособность железяки.
+1
Напишите лучше статью про работу с V-USB.
-1
А статья «прородитель» чем вам не статья по v-usb? или не пойму вы по тегам кликать разучились?
0
Благодарю, ждал год!
))
Но ждал на два канала :)
А как реализовать три входных канала?
0
Если Вы смотрели форму сигнала, то такое ощущение, что срезана отрицательная полуволна. То ли это произошло при конвернации, то ли немного не в том формате гонится сигнал. В любом случае — большое спасибо.
0
Все дело в том, что на вход АЦП подавался сигнал с линейного выхода плеера… А так в принципе Вы правы, отрицательный период отсечен=) Это слышно даже без «вооруженного глаза».
0
Все ясно. Нужно было сместить вход АЦП делителем к половине питания. А к конце композиции конденсатор уже зарядился через диод и тихие звуки записаны полностью.
0
Ну так я это так вроде знаю… Только если вы заметли, то звук в формате 8 бит беззнаковый, т.е. 0 это полная тишина, а 255 макс, молчание 127, а лишние заморочки с перещетом и какм нбудь еше геморроем мне было лень учтывать
0
На самом деле там rar архив исходников с расширением zip
0
Кстати, вот под шумок VUSB хотел бы спросить, можно ли совместить HID Joy и HID User аля я? Т.е. чтобы в системе виделся как джой, но я параллельно мог работать с ним как я хочу?
0
Скорее всего это будет мульти-устройство. Тоесть несколько конфигураций каждая со своими дескрипторами и конечными точками. Иначе вряд-ли. Если вы описываете устройство как джой, то система и драйвера грузит соответствующие, и левые данные эти драйвера не поймут.
0
Ну вроде HID в несколько слоев работает — сперва драйвер USB-HID, который представляет системе абстрактное HID-устройство, а потом уже HID-minidriver для данного класса HID-устройств, который представляет его как джой, клаву или мышь. Вот только не знаю, можно ли общаться с HID-USB драйвером, если поверх него уже висит минидрайвер.
0
должно работать, правда у меня до этого все никак руки не дойдут. Хочу свой контроллер на джой напилить, чтоб заодно эмулятор клавы делал а-ля сайтек, да других задач пока куча.
0
Ну вот здесь он наверно составным должен представляться. Хотя хз. Лучше посмотреть, как представляются клавы и мыши, которые одновременно и тем, и другим прикидываются.
0
Ну, либо полностью пишете свои драйвера и они видят все как Вам надо :)
0
всмысле свои? винда ж по дефолту свои поставит, или не?

Короче, на obdev есть примеры хидов для джоя и для тупо ногодрыгания. По отдельности работают замечательно. Хотел бы объеденить, т.е. есть джой, хочу повесить на него индикатор. Фишка чтобы один ЮСБ шнурок. Т.е. я так понял, теоретически возможно?
0
Да, винда ставит свои дрова, но если устройство зело хитрое или стандартные дрова не устраивают — можно и самому написать.
А Вам проще будетсостыковать эти 2 примера описав составное usb-устройство, одна часть которого будет джойстик, вторая — Ваш юзер-интерфейс. Поройте в сети, может есть примеры на составные устройства.

P.S. Если не секрет: что за индикатор, в какой игре использовать, что индицировать?
0
Flight Simulator. Индицировать всё, что можно индицировать. Ща у меня просто два ЮСБ шнурка, если будет геморно, то так и оставлю.
0
Можно в принципе использовать PID (Physical Device Interface), предназначенный для устройств с Force Feedback. Индикатор можно повесить как какой-то из эффектов PID. Правда, разрабатывался он M$ для своего сайдвиндера и потому такой жуткий, что те же китайцы предпочитают для FF делать свой драйвер.
Не уверен PID ли, но поддержка форсфидбэка есть в USB-адаптере для джойстиков Nintendo 64 и Game Cube (ссылка есть в списке проектов на сайте V-USB).
0
В таком случае нужен составной HID-дескриптор и два вида репортов. Примеры. Но в системе будет отображаться как два разных устройства, если не ошибаюсь.
0
Да, отображается как разные устройства
0
так мне и надо как два разных. один джой, я его не трогаю, а со вторым из делфы обмениваюсь. )
0
очень ждём USB sound card!
0
Уже было где-то… Да и с АВРок я давно слез и перешел на контроллеры по-жирнее. В ближайшем времени выложу статью по проигрывателю медиа-файлов на Cortex-m4. Если у сообщества будет интерес к подобного роду изделиям (usb устройства), попробую выделить время на написания кратеньких статеек. Но по поводу usb звуковой карты по-моему тут уже было
+1
проигрывателю медиа-файлов на Cortex-m4
Что умеет?
0
mp3, acc, mp4, ogg, wav(куда ж без него), flac. В процессе wma, но тут пока только наброски.
+1
*aac
0
MP4 — в смысле видео?
А что вообще девайс из себя представляет, нечто типа PMP?
Какие требования у всего этого, в смысле сколько проца и сколько памяти на декодирование жрет?
0
mp4 как контейнер для звука, не более( видео нет, не видел смысла) 45х55 мм коробочка, одна банка литий-он, сбрам на 8-16Мб, карта микросд, контроллер зарядки и монитор батареи, бак-буст для работы и олед самый дешманский от китайцев. вечером если не забуду скину скрин из кикада
0
А какой смысл в девайсе в целом? В смысле, чем он отличается от всяких там МР3 плееров, коих на всякий вкус и кошелек?
mp4 как контейнер для звука
m4a это называется. В качестве кодеков, как я понимаю, поддерживаются все те же mp3, vorbis, aac?
0
смысл в общем то только академический) отличий думаю вагон — он полностью открыт и можно пилить как тебе угодно. кодеки софтовые, да, Вы правы
0
отличий думаю вагон — он полностью открыт и можно пилить как тебе угодно. кодеки софтовые
Это-то очевидно, я имел в виду отличия с точки зрения потребительских качеств.
сбрам на 8-16Мб
А что такое «сбрам» и зачем она? Встроенной в МК памяти на декодирование не хватает?
0
Потребительская точка зрения у каждого своя, думаю. Для меня — время работы устройства и опыт (хотя на мой взгляд тут ничего сложного), для кого-то другого своя ценность, для третьих — бесцельно потраценное время. Никаких целей далеко идущих не ставил, просто размять мозг, вспомнить схемотехнику, потренироваться в трассировке плат и т.д.

сбрам = SDRAM, очепятка вышла, прошу прощения( основная цель — хранить ресурсы и буферы для воспроизведения, там по сути медленная куча для некритичных библиотек, плейлист, всякая вспомогательная инфа. есть возможность выполнять код оттуда. На макете у меня нормальных экран, гонял там всякие эмуляторы геймбоя и прочее, но в релизе решил убрать) Часть сдрам идет как накопитель usb, через который можно смотреть всякую дребедень на компе, обновлять прошивку и прочее… Хотя если уж очень подумать — играть музыку можно и без нее, такая опция при компилировании есть
0
Для меня — время работы устройства
И сколько оно составляет?
0
пока трудно сказать. приедет плата, соберу и расскажу все в деталях
0
Ну что, как успехи?
0
Пока, к сожалению, плата не готова… Я помню про обещание, обязательно расскажу о результатах в не зависимости от того, какие они будут: успешные или нет)
0
Я тут статью запиливал, потом, на вегалабе есть по мотивам подобный проект (до 192/2/16 и 96/2/24) и Геннадий Завидовский UA1ARN в своем Storch'е сделал UAC1. Это всё на STM32.
0
качество значения не имеет
-1
usb audio, mp3…
на cortex не представляет никакого интереса, для этого есть всё уже давно и даже готовое дешевле.
Не вижу тут никакого творчества.
-1
На самом деле, для UAC2 решений не так-то и много: XMOS, audio-widget на AVR32, C-media 6631 и Tremor
Я ещё и на плиске делал с внешней ULPI PHY
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.