LINUX.ORG.RU

Фактическая частота в ALSA чуть отличается от запрошенной

 ,


0

1

Настраиваю 16000 (через snd_pcm_hw_params_set_rate_near), при этом и с микрофона идёт примерно 15980 и на динамики оно принимает примерно столько же. Пока что решил тупо дропом невлезающих сэмплов (а для стрима с микрофона дублирую примерно 20 штук в секунду равномерно размазанных по секунде, да я догадываюсь что любители чистого звука такой способ ресэмплинга осудят, но не суть).

Так вот, вопрос такой, это нормальная ситуация или надо считать дефектом звуковой карты или какими-то неправильными настройками?

И если нормальная, то как это обычно решается, неужели ресэмплят всё подряд? Или может номинальное 16000 на самом деле должно быть 15980 и его просто округлили?

Не знаю может тема для development, перенесите если надо.

★★★★★
Parameters  
    pcm	PCM handle   
    params	Configuration space   
    val	**approximate** target rate / returned **approximate** set rate   
    dir	Sub unit direction    

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

Ставь 44100 :)

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)

А что, это принципиально использовать экзотическую частоту дискретизации 16000? Нельзя просто 48000 или 44100 выставить?

James_Holden ★★★★★
()
Последнее исправление: James_Holden (всего исправлений: 1)

И если нормальная, то как это обычно решается, неужели ресэмплят всё подряд?

Если ты принимаешь и выдаешь с одной и той же частотой, то проблем нет, если с разными - то ресемплинг в любом случае. Не понимаю сути вопроса.

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

В целом пофигу должно быть что там выставлено, главное чтобы было кратно сколько_бит_на_канал * сколько_каналов можно в теории выставить для стандартного стерео 16 битного значение 32. И получать 1 семпл (один пук в динамике) раз в секунду. Ну, а далее кратно увеличивать. Но внутри может быть свой перерасчёт, я вот в своей воспроизводилке задаю задержку, буферизацию, и надо делать буферизацию от времени кратную дискретизации. Тоесть на деле невозможно выставить произвольный размер буфера и следовательно времени. Возможно что-то подобное и для железок у них есть свои внутрениие эффективные хернюшки под которые подгоняется.

Это когда без ресемпла. А ресемпл это геморой, тьфу его

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от James_Holden

16000 не экзотическая, а вполне стандартная (из ряда 8000, 16000, 24000, 32000, 48000 - последнюю ты сам упомянул уже). Можно ещё 11025 конечно попробовать но подозреваю что там будет та же история. 44100 и прочие большие не годятся.

Вообще я уже не помню почему выбрал именно 16000, возможно в AAC кодеке была какая-то рекомендация на этот счёт или опытным путём установил что меньше заметно плохо а больше не хочу тратить канал зря (большие частоты с низким битрейтом кодека будут шумы делать).

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

Там returned тоже 16000. Я так понял это значит что оно именно его и поставило. Хотя может быть это значит «ок, поставим примерно 16000». Ну а не суть, меня больше интересовал вопрос что с этим дальше обычно делают.

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

Выдаётся то на одном компе а принимается на другом и у них эти «приблизительные частоты» могут отличаться (на втором вообще не алса может быть например, а может эта частота зависит от звукового чипа и гуляет между производителями/моделями или даже экземплярами?), и ситуация ухудшается тем что настоящую частоту алса и не сообщает, её приходится измерять (сравнивая системный таймер и количество полученных от алсы или принятых ей сэмплов, которое может ещё искажаться тем фактом что внутри алсы тоже есть буферы т.е. надо набирать статистику).

Но мне что-то не верится что такая тривиальная задача как переслать звук между устройствами требует обязательного ресемплинга и угадывания настоящей частоты.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)

это нормальная ситуация или надо считать дефектом звуковой карты или какими-то неправильными настройками?

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

как это обычно решается, неужели ресэмплят всё подряд

Просто время «растягивается».

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

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

Ну если это записать звук а потом отдельно проиграть то такое нормально прокатит, а если надо стримить между устройствами? Если тут тоже оставить «как получится» то будут регулярно переполнения или антипереполнения приёмных буферов происходить и дёрганый звук.

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

А это смотря с чем ты борешься, если с пуками, тоесть обрывами, то как Ринат сказал растягивать, если например принимая звук по http бывают моменты обрыва, а потом пакетов наваливает тонну, то ускорять воспроизведение буфера, догоняя поток, второе за меня вот делает openal/sdl, а вот с первым у меня беда, копится задержка, думаю просто раз в период времени сбрасывать очередь воспроизведения если количество буферов на секунду больше чем может быть воспроизведено в секунду.

Уже год хочу всё это починить, но пока никак. А может вообще не смогу, так как я через lua привязки всё дёргаю, а патчить вглубъ love/openal/sdl выискивая причину лень.

Ну и на сборку мусора грешу. Это я всё про то, что непонятна твоя личная проблема которую ты чинишь. Если всё играется нормально, забить болт. Хотя может ты звук пишешь по сети, тогда не знаю, вернее я вообще ничего не знаю, просто свой опыт и проблемы описал.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от firkax

а если надо стримить между устройствами

Буферизируй в микробуферы и ставь их на непрерывную очередь воспроизведения, типа кольцевого буфера в виде связного списка, в листе котрого буфер вмещающий сколько-то милисекунд с учётом дисретизации. Размер 1 микробуфера в кольце буферов будет равен времени отставания звука 6 милисекунд например. А количество буферов в кольце будет равно… ну ты понял =)

Если просто, принял/воспроизвёл, то пердеть будет, на моменте получения новых данных. В теории можно просто 2 буфера первый проигрываешь, во второй принимаешь, затем меняешь местами, но это должно быть всё очень быстро делаться. Да по всякому можно наверное, цена за всякое время отставания звука, за счёт размера буферизации.

Это просто мысли в слух.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3)

Если твои девайсы поддерживает OSS4, поставь и не мучайся.

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

Насколько я знаю, когда нужно реально синхронизировать два девайса, между ними тянут по сути физических два кабеля, один для опорной частоты, другой для сингалов типа «старт».

Для звука это что-то вроде https://en.wikipedia.org/wiki/Word_clock. Интернет в основном сходится на том, что это из разряда аудиофилии.

i-rinat ★★★★★
()
Ответ на: комментарий от firkax

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

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

Если требуется с низкой задержкой синхронизировать, то никуда не денешся, есть ряд методов, начиная с того что ты уже сделал. Если надо качественнее, то методики pitch bend - ускорить/замедлить сигнал во времени. Это на основе SFFT и бесшовной склейки кусков сигнала. Либо применять обычный ресемплинг, если устраивает величина буфера и задержка, которую он потребует.

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

James_Holden ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.