Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.10.2015, 16:04   #1
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
Вопрос Прерывание синхронного воспроизведения звука.

Кратко: есть простейший тред, внутри которого вызывается проигрывание звука из ресурса с помощью API- функции sndPlaySound(). Сам тред создаётся по тыку на кнопке "Start".
Задачи:
1) возможность остановить воспроизведение звука по тыку на кнопку "стоп";
2) если воспроизведение не прерывалось, корректно завершить тред, выйти из Execute() и вызвать тем самым событие OnTerminate.

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

Код:
{$REGION 'TWaveResourcePlayer'}
{ TWaveResourcePlayer }

constructor TWaveResourcePlayer.Create(const AResourceName: string);
begin
  inherited Create(True);
  FID:= Pointer(WAVERESOURCE_PLAYER_TAG); // по умолчанию
  FResourceName:= AResourceName;
end;

destructor TWaveResourcePlayer.Destroy;
begin
  Stop();
  inherited;
end;

procedure TWaveResourcePlayer.Execute;
begin
  Play();
  try
    // цикл треда
    repeat
      Sleep(50);
      // при асинхронном воспроизведении неизвестен момент окончания
    until Terminated;
  finally
    Stop();
  end;
end;

procedure TWaveResourcePlayer.Play;
begin
  PlaySound(PChar(FResourceName), hInstance, SND_RESOURCE or SND_SYNC); // SND_ASYNC ?
end;

procedure TWaveResourcePlayer.Stop;
begin
  PlaySound(nil, 0, 0);
end;

{$ENDREGION}
Решения, основанные на других функциях и прочих bass.dll и т.п. не предлагайте, ибо я про них знаю. Исключение - mciSendString(), но, мне надо воспроизводить звук, в том числе, и из памяти и/или из ресурса и вроде бы эта функция работает только с файлами/устройствами.

Что скажете, господа?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 23.10.2015, 16:28   #2
come-on
Участник клуба
 
Регистрация: 21.10.2015
Сообщений: 1,361
По умолчанию

решение с медиа плеером не подойдет?
http://codeverge.com/embarcadero.del...-files/1059748

иначе думаю что надо узнаваьт длительность и в каком то таймере проверять не закончилось ли еще проигрывание.
come-on вне форума Ответить с цитированием
Старый 23.10.2015, 16:42   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я может и не к месту, но думается мне что стоит обратить внимание на https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx и иже с ней?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.10.2015, 17:15   #4
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
решение с медиа плеером не подойдет?
http://codeverge.com/embarcadero.del...-files/1059748
Теоретически, естественно, да. Но по условию задачи - нет.
Цитата:
иначе думаю что надо узнаваьт длительность и в каком то таймере проверять не закончилось ли еще проигрывание.
Да, это вариант. Квинтэссенция: где взять функцию
Код:
function GetMediaResourceDuration(const resname: string): double;
чтобы не писать её самому? Звук в программе - подзадача не приоритетная, поэтому влом напрягаться. Мож есть у кого чо?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 23.10.2015, 17:27   #5
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Я может и не к месту, но думается мне что стоит обратить внимание на https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx и иже с ней?
слишком круто для воспроизведения звука дверного звонка по кнопке. Необходим вариант сильно проще.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 23.10.2015, 23:17   #6
DIONISKA
Форумчанин
 
Регистрация: 07.11.2011
Сообщений: 161
По умолчанию

Почему-бы не воспроизводить асинхронно, а в потоке просто ждать завершения проигрывания трэка?
предполагаю таким образом:
1) считывать ресурс с трэком в memorystream;
2) из него читать wave-заголовок и рассчитывать приблизительное время;
3) запустить асинхронное воспроизведение из того-же memorystream;
4) отсчитывать в цикле потока ранее рассчитанное время, периодически проверяя свойство "terminated" потока;
5) по завершению таймера/необходимости завершению потока корректно его завершить;
вот примерно так. единственный минус - это погрешность в отсчёте времени, но тут думаю это не так критично.
Вложения
Тип файла: rar ts.rar (196.7 Кб, 13 просмотров)

Последний раз редактировалось DIONISKA; 24.10.2015 в 00:03.
DIONISKA вне форума Ответить с цитированием
Старый 24.10.2015, 00:12   #7
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Почему-бы не воспроизводить асинхронно, а в потоке просто ждать завершения проигрывания трэка?
предполагаю таким образом:
1) считывать ресурс с трэком в memorystream;
2) из него читать wave-заголовок и рассчитывать приблизительное время;
3) запустить асинхронное воспроизведение из того-же memorystream;
4) отсчитывать в цикле потока ранее рассчитанное время, периодически проверяя свойство "terminated" потока;
5) по завершению таймера/необходимости завершению потока корректно его завершить;
вот примерно так. единственный минус - это погрешность в отсчёте времени, но тут думаю это не так критично.
Спасибо.
Я уже так и сделал.
Могу предъявить кусок исходника.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 24.10.2015, 02:22   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Вот эдакая хренотень: видеоскриншот.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 01.11.2015, 17:19   #9
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

----------

Последний раз редактировалось Filka; 01.11.2015 в 17:39.
Filka вне форума Ответить с цитированием
Старый 01.11.2015, 18:10   #10
zvygin1964
Старожил
 
Аватар для zvygin1964
 
Регистрация: 19.06.2013
Сообщений: 2,463
По умолчанию

Цитата:
Сообщение от DIONISKA Посмотреть сообщение
ts.rar (196.7 Кб, 1 просмотров)
.
Ну у меня всё как обычно: при нажатии на F9 " [Fatal Error] sm.dpr(5): File not found: 'Vcl.Forms.dcu' "

Цитата:
Сообщение от min@y™ Посмотреть сообщение
видеоскриншот
,- Красотища !
Репутация: полный "0"

Последний раз редактировалось zvygin1964; 01.11.2015 в 18:14.
zvygin1964 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Текущая запись воспроизведения Teror4uks Мультимедиа в Delphi 0 03.02.2014 17:42
ADO: Динамические поля синхронного просмотра grh БД в Delphi 2 03.10.2012 10:48
Из синхронного сокета в асинхронный nbit C# (си шарп) 0 28.10.2011 04:20
Компоненты для воспроизведения звука saggy Мультимедиа в Delphi 6 08.08.2010 11:26
Программа для воспроизведения тонового звука через промежуток времени Vl-sn Помощь студентам 9 12.03.2010 20:27