Pregunta

¿Existe una forma portátil y no restringida por patentes de reproducir archivos de sonido comprimidos en C#/.Net?Quiero reproducir sonidos breves de "tintineo" sobre varios eventos que ocurren en el programa.

Sistema.Media.SoundPlayer solo puede manejar WAV, pero normalmente son demasiado grandes para integrarlos en una aplicación descargable.El MP3 está protegido con patentes, por lo que incluso si hubiera un descodificador/reproductor totalmente gestionado, su redistribución no sería gratuita.El mejor formato disponible parecería ser OGG Vorbis, pero no tuve suerte de hacer funcionar ninguna biblioteca C# Vorbis (logré extraer un PCM sin formato con csvorbis pero no sé cómo tocarlo después).

No quiero distribuir archivos binarios con mi aplicación ni depender de P/Invoke, ya que el proyecto debería ejecutarse al menos en Windows y Linux.Estoy de acuerdo con agrupar ensamblados .Net siempre que sean compatibles con la licencia GPL.

[esta pregunta es una continuación de una discusión de la lista de correo en mono-dev lista de correo hace un año]

¿Fue útil?

Solución

Finalmente revisé este tema y, con la ayuda de BrokenGlass al escribir el encabezado WAVE, csvorbis actualizado.He agregado un OggDecodeStream que se puede pasar a System.Media.SoundPlayer para simplemente reproducir cualquier transmisión de Ogg Vorbis (compatible).Uso de ejemplo:

using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read))
{
  var player = new SoundPlayer(new OggDecodeStream(file));
  player.PlaySync();
}

"Compatible" en este caso significa "funcionó cuando lo probé".El decodificador está completamente administrado, funciona bien en Microsoft .Net; por el momento, parece haber una regresión en Mono SoundPlayer eso causa distorsión.

Anticuado:

System.Diagnostics.Process.Start("fullPath.mp3");

Estoy sorprendido pero el método que Dinah mencionó realmente funciona.Sin embargo, estaba pensando en jugar sonidos cortos de "jingle" en varios eventos que ocurren en el programa, no quiero lanzar el reproductor multimedia del usuario cada vez que necesito hacer un 'ping!' sonido.

En cuanto al enlace del proyecto de código, lamentablemente es solo un contenedor P/Invoke.

Otros consejos

No quiero distribuir ningún binarios con mi aplicación ni depender de P/Invoke, ya que el proyecto debe ejecutarse al menos en Windows y Linux.Estoy bien con los ensamblados de .NET de la agrupación siempre que sean compatibles con la licencia con GPL.

Desafortunadamente, será imposible evitar la distribución de archivos binarios o evitar P/Invoke.Las bibliotecas de clases .net usan P/Invoke debajo de todos modos, el código administrado tiene que comunicarse con la API del sistema operativo no administrado en algún momento para poder hacer algo.

Convertir el archivo OGG a PCM debería ser posible en código administrado, pero debido a que no hay soporte nativo para audio en .net, realmente tienes 3 opciones:

  1. Llame a un programa externo para reproducir el sonido (como se sugirió anteriormente)

  2. P/Invocar un módulo C para reproducir el sonido

  3. P/Invocar las API del sistema operativo para reproducir el sonido.

(4.) Si solo está ejecutando este código en Windows, probablemente podría usar DirectShow.

P/Invoke se puede utilizar de forma multiplataformahttp://www.mono-project.com/Interop_with_Native_Libraries#Library_Names

Una vez que tenga sus datos PCM (usando OGG C Lib o código administrado, algo como esto http://www.robburke.net/mle/mp3sharp/ (por supuesto, hay problemas de licencia con MP3), necesitará una forma de reproducirlo; desafortunadamente, .net no proporciona ninguna evaluación directa de su tarjeta de sonido ni métodos para reproducir audio en streaming.Puede convertir los archivos ogg a PCM al inicio y luego usar System.Media.SoundPlayer para reproducir los archivos wav generados.El método actual que sugiere Microsoft utiliza P/Invoke para acceder a la API de reproducción de sonido en el sistema operativo. http://msdn.microsoft.com/en-us/library/ms229685.aspx

Una API multiplataforma para reproducir sonido PCM es OpenAL y debería poder reproducir sonido (PCM) utilizando los enlaces de C# para OpenAL en www.taoframework.com. Desafortunadamente, necesitará copiar varios archivos DLL y .so con su aplicación para que funcione cuando se distribuya, pero esto, como expliqué anteriormente, es inevitable.

Llamar a algo que se encuentra en 'System.Diagnostics' para reproducir un sonido me parece una idea bastante mala.Esto es para qué sirve esa función:

    //
    // Summary:
    //     Starts a process resource by specifying the name of a document or application
    //     file and associates the resource with a new System.Diagnostics.Process component.
    //
    // Parameters:
    //   fileName:
    //     The name of a document or application file to run in the process.
    //
    // Returns:
    //     A new System.Diagnostics.Process component that is associated with the process
    //     resource, or null, if no process resource is started (for example, if an
    //     existing process is reused).
    //
    // Exceptions:
    //   System.ComponentModel.Win32Exception:
    //     There was an error in opening the associated file.
    //
    //   System.ObjectDisposedException:
    //     The process object has already been disposed.
    //
    //   System.IO.FileNotFoundException:
    //     The PATH environment variable has a string containing quotes.

Creo que deberías echarle un vistazo a fmod, que es la madre de todas las API de audio.

por favor siéntete libre de soñar http://www.fmod.org/index.php/download#FMODExProgrammersAPI

Las API de XNA Audio funcionan bien en aplicaciones .net/c# y funcionan perfectamente para esta aplicación.Activación basada en eventos, junto con reproducción simultánea de múltiples sonidos.Exactamente lo que quieres.Ah, y compresión también.

Bueno, depende de las leyes relacionadas con patentes de un país determinado, pero, hasta donde yo sé, no hay forma de escribir un decodificador de mp3 sin violar las patentes.Creo que la mejor solución multiplataforma de código abierto para su problema es GStreamer.Tiene enlaces de C#, que evolucionan rápidamente.Sin embargo, usar y crear GStreamer en Windows no es una tarea fácil. Aquí es un buen punto de partida. alma en pena El proyecto utiliza este enfoque, pero todavía no se puede utilizar en Windows (sin embargo, hay algunas compilaciones nocturnas que casi funcionan). FMOD También es una buena alternativa.Desafortunadamente, no es de código abierto y encuentro que su API tiene de alguna manera un estilo C.

Hay un decodificador vorbis de C# puro disponible que es de código abierto:

http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/

No estoy seguro si esto sigue siendo relevante.La solución más sencilla sería utilizar NAudio, que es una API de audio de código abierto administrada escrita en C#.Otra cosa que puedes probar sería utilizar ffmpeg y crear un proceso para ffplay.exe (los binarios correctos están en compilaciones compartidas).

No hay manera de que puedas hacer esto sin usar algo más para manejar tu juego.

El uso de System.Diagnostic iniciará un software externo y dudo que quieras eso, ¿verdad?Solo quieres que el archivo de sonido X se reproduzca en segundo plano cuando suceda Y en tu programa, ¿verdad?

Votado a favor porque parece una pregunta interesante.:D

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top