2009-08-16 49 views
10

1에서 9까지의 각 키가 다른 사운드를 생성하는 샘플러 프로그램을 만들고 있습니다. 모든 것이 잘 작동하지만 두 개 (또는 그 이상)의 소리를 동시에 누르면 두 번째 소리가 첫 번째 소리를 "죽입니다".SoundPlayer를 사용하여 여러 사운드 재생

SoundPlayer을 사용하여 .WAV 파일에서 소리를 재생하고 있습니다. 이 문제를 어떻게 해결할 수 있습니까?

답변

6

DirectX (DirectSound) 또는 여러 사운드를 동시에 재생할 수 있도록 설계된 유사한 API를 사용해야합니다.

1

KeyPress 이벤트 (또는 무엇을 사용하든)에서 WAV 파일에 대한 경로를 사용하는 생성자를 사용하여 SoundPlayer의 새 인스턴스를 만든 다음 해당 Play 메서드를 호출하는 것으로 추측합니다. 이론적으로 Windows 98 이후 Windows에서 여러 개의 WAV 파일을 동시에 재생할 수 있으므로 "모노"효과가 발생해서는 안됩니다.이 클래스를 직접 사용하여 듣는 것 같아요. 두 번째가 시작될 때 첫 번째 사운드를 차단하지 않지만 실제로는 WAV 파일이 디스크에서로드 될 때 일시 중지되는 전체 재생으로 인해 생기는 결함입니다.

각 키를 누를 때마다 SoundPlayer의 새 인스턴스를로드하는 대신 클래스 범위의 SoundPlayer 개체의 배열을 만들어 양식의 Load 이벤트에서 디스크에서 미리로드 해보십시오. 그런 다음 키를 누를 때 각 SoundPlayer의 Play 메서드를 호출하면됩니다. 이것은 당신의 문제를 해결할 수 있습니다, 비록 당신이 여전히 가끔씩 이런 식으로 생각할지라도.

6

C# 또는 VB.Net에서 한 번에 여러 사운드를 재생하는 간단한 방법이 있습니다. 각 .wav 파일을 재생하려면 mciSendString() API 함수를 호출해야합니다. 루프 재생을하지 않는 한 멀티 스레딩을 할 필요가 없습니다. Here은 을 사용하여 생성 된 MusicPlayer 클래스의 전체 작동 예제입니다.

// Sound api functions 
[DllImport("winmm.dll")] 
static extern Int32 mciSendString(string command, StringBuilder buffer, int bufferSize, IntPtr hwndCallback); 

위의 기능에서 키는 첫 번째 매개 변수 명령입니다. 별도의 명령 이름을 사용하여 두 개의 함수를 호출하는 한 개별적으로 동시에 재생됩니다. 이것은 내가 C# 프로그램 중 하나에서 한 것입니다.

private void PlayWorker() 
{ 
    StringBuilder sb = new StringBuilder(); 
    mciSendString("open \"" + FileName + "\" alias " + this.TrackName, sb, 0, IntPtr.Zero); 
    mciSendString("play " + this.TrackName, sb, 0, IntPtr.Zero); 
    IsBeingPlayed = true; 
} 

편집 : 실제 예제에 대한 링크가 추가되었습니다.

+0

매번 새로운 고유 한 트랙 이름을 보내는 경우에만 작동하지만 이는 의도적으로 설계된 것입니까?이전에 사용한 트랙 이름에서 다른 사운드를 재생하려고하면 (심지어 첫 번째 정지 된 후에도 오래 걸릴 것입니다) 소리가 나지 않습니다. – Sire

+0

@Sire 그렇게해서는 안됩니다. 재생이 완료된 후 "정지"명령과 "닫기"명령을 전송 하시겠습니까? 내 전체 MusicPlayer 구현 [여기] (http://pastebin.com/TtrCdeER)을 참조 할 수 있습니다. 오디오 재생을 위해 스레드 내부에서 호출되는 PlayWorker()에 특히주의하십시오. –

+0

전체 코드를 보내 주셔서 감사합니다! 나는 그 링크를 답에 추가 할 것이다. – Sire

3

이 작업을 수행 할 수 있습니다 :

SoundPlayer

는 WAV 스트림을 지원합니다. 당신은

  • MIX 샘플 당신이 '로 손'재생하고,
  • 가짜 수 (어딘가에서 WAV 헤더를 얻을, 그것은 복잡 아니다).

매개 변수로 그러한 스트림을 the SoundPlayer constructor에 제공하십시오.

그런 식으로 복잡한 DirectSound 라이브러리를 사용할 필요없이 믹싱을 한 번에 할 수 있습니다.

1
using System.Windows.Media 

Function void Play(string audioPath) 
{ 
MediaPlayer myPlayer = new MediaPlayer(); 
myPlayer.Open(new System.Uri(audioPath)); 
myPlayer.Play(); 
} 

Play(Application.StartupPath + "\\Track1.wav"); 
Play(Application.StartupPath + "\\Track2.wav"); 

이 코드는 동시에 오디오 파일을 재생할 수, 두 번째 오디오 track2.wav의 호출은 track1.wav의 재생을 방해하지 않습니다.

+0

좋은 해결책입니다. 2 가지 질문 : 1. 분명히 'MediaPlayer'내에 '로드'가 없습니다. 그것은 그것없이 아직도 작동합니다. 2. 첫 번째 파일 바로 다음에 다른 mPlayer.Play()를 추가하면 오디오 파일이 두 번 재생되지 않지만 한 번 - 왜 그럴까요? – HeyJude

+0

로드 방법이 SoundPlayer에 있으면 수정됩니다. 둘째, 다른 오디오 파일을 전달하기 때문에 오디오 파일을 두 번 재생하지 않습니다. Track1.wav, Track2.wav. – Vijayaraghavan

+0

@Pransesh, 내 의도를 분명히하자. 내가 의미하는 바는 다음과 같다.'Function void Play (string audioPath) {... myPlayer.Play(); myPlayer.Play(); } '그러면 Play는 두 번이 아니라 한 번 실행됩니다. 왜? – HeyJude