LINUX.ORG.RU

ALC897 на материнке некорректно работает с S/PDIF

 alc897, ,


0

1

Вообще, хочу странного, а именно кодировать 6-ти канальный PCM в AAC, а затем пихать это в iec958. И это даже работало, пока не пришлось сменить звуковуху с Xonar на встройку с ALC897.

Симптомы следующие, с дефолтными параметрами, звук в каждом канале идет полсекунды и пропадает:

$ speaker-test -c 6 -t wav -Da52

speaker-test 1.2.2

Устройство для проигрывания - a52
Параметры потока - 48000Гц, S16_LE, 6 каналов
WAV файл(ы)
Установлена частота в 48000Гц (запрошено 48000Гц)
Размер буфера от 3072 до 1047552
Размер периода от 1536 до 1536
Используется максимальный размер буфера 1047552
Периоды = 4
был установлен period_size = 1536
был установлен buffer_size = 1047552
 0 - Front Left
 4 - Front Center
 1 - Front Right
 3 - Rear Right
 2 - Rear Left
 5 - LFE
Время в периоде = 6,264622

Однако стоит задать размер буфера меньше максимального, и звук приходит в норму:

$ speaker-test -b 1024 -c 6 -t wav -Da52

speaker-test 1.2.2

Устройство для проигрывания - a52
Параметры потока - 48000Гц, S16_LE, 6 каналов
WAV файл(ы)
Установлена частота в 48000Гц (запрошено 48000Гц)
Размер буфера от 3072 до 1047552
Размер периода от 1536 до 1536
Запрошено время предзагрузки 1024 мс
Периоды = 4
был установлен period_size = 1536
был установлен buffer_size = 3072
 0 - Front Left
 4 - Front Center
 1 - Front Right
 3 - Rear Right
 2 - Rear Left
 5 - LFE
Время в периоде = 8,582677

Собственно, это упрощенный до предела пример, проблема проявляется в любом медиаплеере, смотреть видео стало невозможно - полсекунды звука и 10 секунд тишины. Как задать размер буфера для всех клиентов алсы? Ну или на худой конец, для vlc или mplayer?

★★★★★

Если совсем грубо - судя по тому, что speaker-test по -b только и делает, что вызывает snd_pcm_hw_params_set_buffer_size_near(), то, наверное, можно расковырять /alsa-plugins-1.2.7.1/a52/pcm_a52.c и захардкодить там вместо:

buffer_size = io->buffer_size;
	if ((err = snd_pcm_hw_params_set_buffer_size_near(rec->slave, rec->hw_params,
							  &buffer_size)) < 0) {
		SNDERR("Cannot set slave buffer size %ld", buffer_size);
		return err;
	}
подходящее значение )

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

Как я понимаю, так в лоб не получится, тогда в клиентском приложении будет один размер буфера, а в pcm другой, заикаться будет.

UPD: ещё веселее, хардкодишь маленький буфер - вообще чуть пищит каждый канал и на другой сразу же перескакивает.

 speaker-test -c 6 -t wav -Da52

speaker-test 1.2.2

Устройство для проигрывания - a52
Параметры потока - 48000Гц, S16_LE, 6 каналов
WAV файл(ы)
Установлена частота в 48000Гц (запрошено 48000Гц)
Размер буфера от 3072 до 1047552
Размер периода от 1536 до 1536
Используется максимальный размер буфера 1047552
Периоды = 4
был установлен period_size = 1536
был установлен buffer_size = 1047552
 0 - Front Left
 4 - Front Center
 1 - Front Right
 3 - Rear Right
 2 - Rear Left
 5 - LFE
Время в периоде = 0,705866

Ну и сообветственно весь цикл проигрывает меньше чем за секунду.

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

Я вот теперь думаю, в Xonar это работало, получается, на встройке какая-то проблема с буфером. В опциях snd-hda-intel есть только выравнивание размера буфера по 128, но оно ничего не дает, больше ничего похожего…

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

Как задать размер буфера для всех клиентов алсы?

Читать доку и писать свой .asoundrc, вестимо. Использовать какой-то из плагинов, позволяющих задавать размер буфера (dmix точно может, возможно, и более простые типа copy тоже), а к нему уже в качестве слейва подцеплять hw:a52. Какой конкретно плагин использовать — зависит от сетапа. Может, вообще параметры дефолтного устройства достаточно изменить, типа defaults.dmix.a52.periods = 4.

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

Мысль была хорошая, но увы, все плагины, позволяющие задавать размер буфера, требуют в качестве слейва hw, а a52 - rate:

pcm.a52 {
  @args [CARD]
  @args.CARD {
    type string
  }
  type rate
    slave {
      pcm {
        type a52
        channels 6
        card $CARD
      }
      rate 48000
  }

  hint {
      show {
          @func refer
          name defaults.namehint.basic
      }
      description "AAC Encoding through IEC958 (S/PDIF)"
      device $DEV
  }
}
eagleivg ★★★★★
() автор топика
Ответ на: комментарий от eagleivg

В опциях snd-hda-intel есть только выравнивание размера буфера по 128, но оно ничего не дает, больше ничего похожего…

На мимопроходящий взгляд - position_fix выглядит похожим )

module_param_array(position_fix, int, NULL, 0444);
MODULE_PARM_DESC(position_fix, "DMA pointer read method."
		 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO).");
Особенно почему-то нравится 6 = FIFO

Жаль не могу поиграть в вашу игру. Без настоящего S/PDIF только шум слышу в speaker-test -t wav -c 6 -D"plug:{SLAVE=\"a52:1,'hw:1,0'\"}".

)

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

На мимопроходящий взгляд - position_fix выглядит похожим )

Ви таки будете с меня смеяться…

Но options snd_hda_intel position_fix=1 сработал. А почему я сразу этого не понял - я тестил параметры со speaker-test, там звук как заикался так и заикается, а вот в плеерах нормально работает.

Если что, нашел здесь https://forum.linuxmce.org/index.php?topic=5845.15 когда искал совсем другое.

eagleivg ★★★★★
() автор топика