LINUX.ORG.RU

Может ли в дешёвой звуковухе (встроенная в ноуте) ЧД быть немного отклонённой от заявленной?


0

2

Ну например сказано, что её аппаратная ЧД (частота дискретизации) - 48000. Может ли в реальном ЦАП, т.е. в реальном железе она плавать между 47800 и 47990?

Ситуация:

Вывожу звук одновременно с рисованием его графического представления (спектр-сонограмма). Графика выводится точно, хотя кадры ресуются не через равные промежутки времени (Qt-шный QTimer с его погрешностями). Точность позиции курсора на графике в каждом кадре обеспечивается за счёт того, что когда приходит запрос на рисование кадра, я беру точное текущее время с помощью вот такой функции:

long long getCurrentTimeMs(void)
{
	boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
	boost::posix_time::ptime	epoch_start(boost::gregorian::date(1970,1,1));
	boost::posix_time::time_duration dur = now - epoch_start;
	return dur.total_milliseconds();
}

и на основании разницы со временем старта воспроизведения звука принимаю решение, какое место файла рисовать напротив курсора. Это элементарно сделать, зная его ЧД. Ну например если пришёл запрос на рисование кадра и я вижу, что с момента начала воспроизведения прошла 1 секунда, я должен нарисовать напротив курсора район 44100-го семпла, при ЧД=44100. То есть при любой неточной частоте кадров я рисую точную картинку.

Запускаю воспроизведение, смотрю на картинку, сопоставляя слышимое и видимое. В районе 150-й секунды становится заметно, что картинка уехала вперёд где-то на 1/10 секунды.

Если считать, что getCurrentTimeMs() даёт точное текущее время, то получается, что звуковуха воспроизводит немного медленнее, чем нужно. То есть аудиофилы на форумах не зря точность тактового генератора обсуждают?

Да, файл 44100, а звуковуха 48000. Ресемплинг делает ALSA где-то внутри себя - меня это мало волнует, т.к. пакеты семплов я ей поставляю по коллбеку исправно без тормозов, т.е. внутри аппаратуры пакеты семплов, которые ALSA у меня просит состыковываются идеально, иначе я бы щелчки слышал в наушниках.

Загрузка данных из файла - большими кусками, асинхронно, в отдельном потоке. ALSA просит очень мелкими кусками - по 940 семпла, я отдаю ей уже из готовых загруженных буферов (длина секунды по 4), то есть при обработке коллбека никто ничё с диска не читает, максимум - семафор дёргается, чтобы загрузку будущих отдалённых данных в фоне запускать.

Ещё есть известная в узких кругах софтина baudline, которая каким-то образом (по системным часам наверное) меряет ЧД при воспроизведении и записи. Наверное запихивает в ALSA пакеты и меряет, сколько данных ей удаётся пропихнуть в единицу времени... В общем в режиме «48000» она выдаёт колеблющееся число между 47995 и 48000.

Видео о происходящем: http://youtu.be/H3Fv0-6-oZs

P.S. Померял скорость трафика в семплах между модулем загрузки данных и модулем воспроизведения, получилось 44055.1...44066.2 семпла в секунду. До 44100 не дотягивает. Этот «трафик» определяется коллбеками от ALSA, никакой самодеятельности нет, щелчков в звуке тоже нет, всё слышно очень ровно, сколько ALSA просит, столько исправно даём без сбоев и тормозов.

★☆

Последнее исправление: kiverattes (всего исправлений: 2)

ну - скажем так
у любых 2 таймеров - ВСЕГДА есть мелкие но различия в частоте
и если ты делаеш 2 действия - одно из которого завязано на одном таймере - а второе на втором - то ошибка будет накапливаться

вопрос лиш в величине этой ошибки

вывод - надо или синхронизировать - или опираться только на один таймер

ae1234 ★★
()

Частота с которой тактируется ЦАП может отличаться (на практике почти всегда отличается) от заявленного эталона, вопрос только в погрешности.

m0rph ★★★★★
()

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

kiverattes ★☆
() автор топика

А если на двух помпах завести просто синус кил на 6? По идее ежели есть расхождения, то должны быть слышны биения.

anonymous
()

Точность позиции курсора на графике в каждом кадре обеспечивается за счёт того, что когда приходит запрос на рисование кадра, я беру точное текущее время

А почему бы просто не рассчитывать позицию на графике по номеру последнего сэмпла, считая частоту дискретизации правильной и постоянной? Сдается мне, что проблема в неточности таймера getCurrentTimeMs()

Если вопрос принципиальный, попробуй осциллографом измерить :)

Harald ★★★★★
()
Ответ на: комментарий от anonymous

А если снизить частоту, можно пилить хардварный дабстеп! ХОТЕТ!

jessey
()
Ответ на: комментарий от Harald

попробуй осциллографом измерить

1-5 Гц на уровне частоты 48000 Гц? Тут нужен либо хитрый спектроанализатор либо осциллограф совсем умный. Проще биения попробывать померять с двух девайсов.

ebantrop
()
Ответ на: комментарий от Harald

Позицию курсора рассчитывать по последнему семплу тяжело, поскольку семплы отправляются в звуковуху большими пакетами и какой конкретно сейчас воспроизводится сказать тяжело. В windows, например, пакеты могут быть вообще длиной в пару секунд, это вот ALSA жрёт мелкие пакеты по 940...1024 семпла...

kiverattes ★☆
() автор топика
Ответ на: комментарий от ebantrop

1-5 Гц на уровне частоты 48000 Гц? Тут нужен либо хитрый спектроанализатор либо осциллограф совсем умный. Проще биения попробывать померять с двух девайсов.

44100-44083 = 17. 17/2 = 8 гц отклонения. Это ухом трудно заметить, если совсем не невозможно, но цифра какая-то на первый взгляд большая. Целых 8 гц...

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

http://en.wikipedia.org/wiki/Beat_(acoustics)

Слышно будет не 8 Гц, а основную частоту модулированную 8мю герцами. Ну или что там получится по разности частот. Либо осциллографом, но опять же реально посмотреть только разницу. Поэтому нужен еще референс генератор. Самое простое взять вторую звуковую карту.

ebantrop
()
Ответ на: комментарий от kiverattes

Либо еще проще. Воспользоваться прекрасным изобретением придворного трубача английской королевы 1711 года — камертоном. И осциллограф не понадобится :)

ebantrop
()

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

x905 ★★★★★
()
Ответ на: комментарий от x905

Незнаю через что работает baudline. Иногда он не хочет работать, тогда я прибиваю все процессы, захватившие (кажется) /dev/snd/pcm и всё ОК.

kiverattes ★☆
() автор топика

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

x905 ★★★★★
()
Ответ на: комментарий от x905

Секундомер сертифицированный - нету, времени - нету, измерения трафика на вопрос ответили, с людьми в реале поговорил, которые звуковые редакторы писали - они такое замечали (под виндой позицию текущего семпла у винды спрашивают и по нему графику рисуют), на stackoverflow подтвердили, что «распространённая хрень», так что считаю ответ найденным )

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

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

x905 ★★★★★
()
Ответ на: комментарий от x905

Данных отдаётся столько, сколько нужно, просто медленнее. С этим ничего не поделать, если необходима аудиофилия - апргейд ЦАП-а.

kiverattes ★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.