Звук воспроизводится только один раз в tcl/tk (закуска, pulseaudio, Linux)

Я использую пакет закусок в Linux Mint 13 (Maya), tk8.5 (желание).

Мой аудиовыход представляет собой аналоговое стерео с программным обеспечением pulseaudio.

В соответствии с этим: http://www.speech.kth.se/snack/tutorial.html все, что мне нужно сделать, чтобы воспроизвести звук снова, это снова использовать команду воспроизведения.

У меня есть звуковой объект, и он воспроизводится только один раз, независимо от того, сколько раз я вызываю команду play.

Я попытался поставить команду stop перед воспроизведением, например:

mysound stop
mysound play

Что происходит: играет на первом звонке, но не на втором, играет на третьем, но не на четвертом звонке, и так далее. Это асинхронно, что означает, что я нажимал кнопки, чтобы повторить стоп-плей. Теперь этот скрипт:

пакет требует закуски

snack::sound s
s read knock.wav
after 1000 {s play}; #play sound effect
after 5000 {s play}; #this one doesn't work
after 10000 {s play}; #this one doesn't work
after 15000 {s stop; s play}; #played
after 20000 {s stop; s play}; #not played
after 25000 {s stop; s play}; #played

То же поведение, что и при использовании событий отпускания кнопки. В Android поведение работает точно так же, как и в теории, за исключением того, что оно имеет огромные задержки в зависимости от устройства (например, звук появляется через 2 секунды на одном телефоне и через 200 мс на другом с лучшим оборудованием).

Я знаю, что теория верна, и мой последний вопрос: как я могу улучшить реализацию Linux, которая использует более надежное воспроизведение звука? Возможно, с использованием миди-звуков. Решение, которое может работать на любой машине UNIX. Обеспечивает ли закуска это?

Спасибо большое, это очень важно для меня и, думаю, для других тоже!


person Judismar Arpini Junior    schedule 12.03.2016    source источник


Ответы (2)


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

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

package require sound
snack::sound s1 -load longrunning-audio.wav
s1 play
# wait
s1 stop
s1 play
s1 pause
s1 pause; # resumes playing

Я использую пакет sound вместо snack, потому что здесь нам не нужны графические элементы.

И как сценарий

#!/usr/bin/env tclsh

package require sound

snack::sound s1 -load longrunning-audio.wav
puts "play"; s1 play
after 4000 puts "stop" \; s1 stop
after 6000 puts "play" \; s1 play
after 10000 puts "pause" \; s1 pause
after 12000 puts "resume" \; s1 pause;
after 16000 {apply {{} {
    puts "stop and exit"
    s1 stop
    exit
}}}

# start the event loop
vwait forever

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

Возможно, вы страдаете от плохо упакованной закуски или ваша аудиосистема дурачит вас. Помню аналогичную проблему с какой-то версией pulseaudio в связке с одним из устройств вывода. Воспроизводилось только начало звука, но аудиосистема оставалась активной (используйте snack::audio active, чтобы показать текущее состояние).

person Uwe Koloska    schedule 12.03.2016
comment
Огромное спасибо! Я рад узнать, что теория, стоящая за этим, в порядке. Я предоставлю код и дополнительную информацию, как вы просили, но я не могу сделать это прямо сейчас. - person Judismar Arpini Junior; 12.03.2016
comment
Я только что обновил вопрос. Однако я удовлетворен вашим ответом: я знаю, что это работает в теории. :) Интересно, как заставить его работать в моей системе. Надеюсь, это поможет другим начинающим перекусить. - person Judismar Arpini Junior; 12.03.2016
comment
Пока не могу комментировать вопрос (пожалуйста, проголосуйте!). Вы должны знать, что все команды after запускаются одновременно, поэтому все со временем 1000 выполняются одновременно по порядку. Из вашего вопроса не ясно, что такое ничего. Чтобы увидеть, что происходит, добавьте puts 1 (с увеличением числа) перед каждой командой after. У меня (archlinux с пульсаудио и текущий снэк с поддержкой alsa) звук воспроизводится два раза: на 1000 и 3000 мс. - person Uwe Koloska; 12.03.2016
comment
Я отредактирую вопрос. Спасибо за внимание. Я просто улучшил скрипт таким образом, чтобы поведение было асинхронным. - person Judismar Arpini Junior; 13.03.2016

Вау, у вас запланировано множество сценариев обратного вызова одновременно! Сами вызовы after занимают очень мало времени. Это означает, что у вас есть несколько вызовов s play практически одновременно. Вы в курсе, что только последний такой будет иметь какой-то эффект? Фактически это так, как если бы вы сделали это (в временном интервале «1000 мс»):

s play
s play
s stop; s play
s stop; s play
s stop; s play

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

Я считаю, что звуковой объект s может только играть или не играть. Кроме того, звуки не воспроизводятся мгновенно (очевидно), поэтому вам нужно время от начала воспроизведения до его остановки, если вы хотите, чтобы звук был слышен. Выполнение того, что вы делаете, приведет к большой активности на уровне обработки команд, но не так много будет заметно.

person Donal Fellows    schedule 12.03.2016