Как воспроизвести несколько файлов .wav одновременно в Delphi - PullRequest
1 голос
/ 25 августа 2010

Я хочу, чтобы несколько файлов .wav одновременно в delphi.

Когда я открываю и платлю, все в порядке. Однако второй вызывает ошибку при попытке открыть.

Может показаться, что я могу использовать только один медиаплеер одновременно ... Есть ли способ обойти это, что мне делать?

Ответы [ 5 ]

4 голосов
/ 25 августа 2010

Как бы вы сыграли один звук? Когда я хочу точного управления, я использую функции waveOut, как в этот ответ . Мой ответ там также позволяет воспроизводить звук с помощью потока (то есть, помимо прочего, асинхронно). Я думаю , что вы можете воспроизводить два звука одновременно, просто запустив два таких потока одновременно, если вы замените только глобальные var с глобальными threadvar с.

Обновление

Самый простой способ воспроизвести один звук - это использовать PlaySound. Это можно использовать асинхронно, но поскольку вы задаете этот вопрос, я предполагаю, что это не позволяет вам использовать эту функцию дважды подряд, чтобы начать одновременное воспроизведение двух файлов. Но: если вы создаете поток, который воспроизводит только звук ( синхронно , так что поток не умирает до окончания воспроизведения), тогда вы можете , вероятно, использовать два таких потока для Воспроизведение двух аудио файлов одновременно. (У меня сейчас нет доступа к компилятору Delphi, поэтому я боюсь, что не могу проверить свои гипотезы.)

Обновление 2

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

procedure TForm1.FormCreate(Sender: TObject);
begin
  with TSoundPlayerThread.Create(true) do
  begin
    SetFileName('C:\Users\Andreas Rejbrand\Downloads\Anna.wav');
    FreeOnTerminate := true;
    Resume;
  end;

  with TSoundPlayerThread.Create(true) do
  begin
    SetFileName('C:\Users\Andreas Rejbrand\Downloads\Mike.wav');
    FreeOnTerminate := true;
    Resume;
  end;
end;

с

unit SoundPlayerThread;

interface

uses
  Classes, MMSystem, Windows;

type
  TSoundPlayerThread = class(TThread)
  private
    { Private declarations }
    FAudioFileName: string;
  protected
    procedure Execute; override;
  public
    procedure SetFileName(const FileName: string);
  end;

implementation

procedure TSoundPlayerThread.Execute;
begin
  PlaySound(PChar(FAudioFileName), 0, SND_SYNC);
end;

procedure TSoundPlayerThread.SetFileName(const FileName: string);
begin
  FAudioFileName := FileName;
end;

end.

и воспроизводился только последний волновой файл.

Обновление 3

На самом деле я написал небольшую библиотеку файлов WAV. Используя это, я могу загрузить два файла WAV, объединить их и отправить результат в аудиодрайвер. Тем не менее, это слишком много кода, чтобы размещать здесь. Если у меня останется время, я могу написать более легкую PlaySimultaneously процедуру и опубликовать ее.

В противном случае: DirectX?

2 голосов
/ 25 августа 2010

Вы можете использовать Фильтр преобразования DirectShow . Это интерфейс программирования приложений (API) Microsoft Windows, который позволяет приложениям Windows взаимодействовать с устройствами ввода Windows Media и управлять ими,

Или вы можете использовать WaveMix DLL - это утилита, которая позволяет воспроизводить несколько файлов WAV одновременно. Он разработан так, чтобы быть максимально простым в использовании, но при этом обладать способностью делать то, что требуется играм. DLL поддерживает 8 каналов одновременного воспроизведения волн, возможность ставить в очередь волны по одному каналу и уведомление о завершении волны.

1 голос
/ 18 апреля 2011

Я сделал это, сделав что-то вроде этого:

//yup, i used more than 1 MediaPlayer controls.
MediaPlayer1.FileName:='song1.wav';
MediaPlayer2.FileName:='song2.wav';
MediaPlayer1.Open;
MediaPlayer2.Open;
MediaPlayer1.Play;
MediaPlayer2.Play;


//the next lines of code is checked every so often in my Timer event handler.
if MediaPlayer1.Position=MediaPlayer1.Length then begin
       MediaPlayer1.Close;
end;

if MediaPlayer2.Position=MediaPlayer2.Length then begin
       MediaPlayer2.Close;
end;
0 голосов
/ 16 января 2017

я думаю, что мы можем использовать

sndPlaySound('filename1.wav',SND_SYN OR SND_NODEFAULT);
sndPlaySound('filename2.wav',SND_SYN OR SND_NODEFAULT);
sndPlaySound('filename3.wav',SND_SYN OR SND_NODEFAULT);
sndPlaySound('filename4.wav',SND_SYN OR SND_NODEFAULT);
0 голосов
/ 25 августа 2010

Для этого вы можете использовать SoX (Sound eXchange) . Он может воспроизводить и записывать аудиофайлы, применять различные эффекты, конвертировать различные форматы ....
Проверьте параметр -m для одновременного воспроизведения файлов. Пример:

sox -m 1.wav 2.wav -d
...