Reputation: 2555
I'm porting an app from wp8 that requires playback of various sounds that can overlap. The only way I've found so far it to use MediaElement, but this doesn't allow overlapping sounds.
QUESTION - what is the easiest and best audio engine to use to play overlapping audio? Ideally I need a small example of how I can do this.
I've looked into WASAPI (http://code.msdn.microsoft.com/windowsapps/Windows-Audio-Session-22dcab6b), but it doesn't look like it supports simple playback ?
Maybe I can wrap the MediaFoundation and call it from winrt? (MediaEngine audio playback on WinRT)
Here is my code now, but when I play a new sound it cuts off the previously playing one rather than blending them.
ThreadUtility.runOnUiThread(
async delegate()
{
// TODO doesn't allow sounds to overlap!
Uri uri = new Uri(R.base_uri, R.raw.URI_PREFIX + resourceId);
StorageFile storageFile =
await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(
uri);
MediaElement element = new MediaElement();
var randomAccessStream = await storageFile.OpenReadAsync();
element.SetSource(randomAccessStream, storageFile.ContentType);
element.Volume = volume;
element.PlaybackRate = pitch;
//TODO element.Pan = pan;
element.Play();
}
);
SOLUTION (as per Filip's answer):
in the page class:
var mediaElements = new LinkedList<MediaElement>();
{
for (int channel = 0; channel < TeacherSoundGroover.NUM_CHANNELS; channel++)
{
var mediaElement = new MediaElement();
mediaElements.add(mediaElement);
// Must be in the tree otherwise it won't overlap!
m_titlePanel.Children.Add(mediaElement);
}
}
m_soundPlayer = new MySoundPlayer(mediaElements);
}
in the MySoundPlayer class:
ThreadUtility.runOnUiThread(
async delegate()
{
Uri uri = new Uri(R.base_uri, R.raw.URI_PREFIX + resourceId);
StorageFile storageFile =
await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(
uri);
if(m_mediaElements != null)
{
int count = m_mediaElements.size();
if (count > 0)
{
int channel = m_nextMediaElementToUse % count;
m_nextMediaElementToUse++;
MediaElement element = m_mediaElements.get(channel);
var randomAccessStream = await storageFile.OpenReadAsync();
element.Stop();
element.DefaultPlaybackRate = rate;
element.SetSource(randomAccessStream, storageFile.ContentType);
element.Volume = volume;
element.Balance = pan;
element.Play();
}
}
}
);
Upvotes: 0
Views: 764
Reputation: 31724
The easiest thing to do is use multiple MediaElement controls, though that might not give you desired results. The best way is to use XAudio2 either directly or through SharpDX if you want to avoid creating a C++/CX WinRT component.
Upvotes: 2