What is a good tool for programmatically playing m

2019-07-19 07:43发布

问题:

I need something that will allow my program to play several audio files (.wav and/or .mp3) at the same time. It would be ideal if I could simply pass a file path to some method, and it will play that file without me having to worry about any of the details.

Additional requirements:

1) I need to be able to programmatically start and stop the playing of any audio file at any time.

2) I need to know when each audio file has finished playing (by either responding to an event or by knowing the duration of the sound file (samples, seconds, etc.) through some property)

3) This tool must be able to play .wav (and preferably .mp3) files of any length/duration.

4) This tool must be able to play multiple audio files at the same time (preferably at least 5 or 6 audio files at the same time).

I have already tried using SlimDX and SharpDX, but I could not find any way of programmatically determining when the file has stopped playing, or of finding the duration (length) of the file.

EDIT:

I believe I found what I was looking for! GStreamer seems to do everything that I was asking for. http://www.gstreamer.com/

回答1:

All audio APIs will allow playback of multiple files simultaneously (mixing takes places behind the scenes, you don't need to worry about it).

Native APIs:

  • waveOut* family of functions, ACM for decompression
  • DirectSound (playback)
  • DirectShow (decoding, playback)
  • WASAPI (playback)
  • Media Foundation

Or, use NAudio for C# wrapper for the mentioned above. You will find a number of posts on NAudio right here on StackOverflow when you need certain details and code snippets.



回答2:

The generic answer to this question (good for most of the how do I play multiple samples at once in frameworks/language X questions) is to software mix the files together.

This has the benefit of giving you complete control of when the individual audio streams start and stop and of synchronisation - something that is typically very difficult when using higher level media player components.

To steps for doing this are:

  1. Load (and format convert/decode) all audio to be output into a memory buffer
  2. For every audio file playing at a given instant in time, mix the corresponding sample from each file by adding them together.
  3. [Not always necessary] adjust the gain of the resulting sample - typically this is division by the number of samples mixed
  4. Store the result into another memory buffer

You have now reduced your problem to a single audio stream to output. Most likely you use your framework of choice's audio output APIs, which periodically request a buffer of samples to output.

If your audio streams are large, the problem becomes a bit more complex as you will need to process your input streams a bit at a time.