2009-10-29 19 views
8

Necesito crear un sonido que contenga tonos de muchas frecuencias diferentes. ¿Hay alguna manera de hacer esto en C#?¿Es posible generar tonos complejos en C#?

Los únicos métodos de generación de tonos que he visto hasta ahora incluyen console.beep, que funciona, pero solo para tonos puros (frecuencias únicas).

+0

Para su información, no es una buena práctica usar el parlante de la computadora (para pitidos). Debe usar la salida de audio predeterminada. – decasteljau

+0

Preferiría usar la salida de audio predeterminada. Eventualmente * necesitará * ser a través de auriculares. –

+4

Ese es un punto importante. Olvídate de Beep. Desea utilizar DirectSound o WaveOut. Ambas son API no administradas, por lo que tendrá que usar PInvoke o cambiar a C++/CLI como su idioma. – CannibalSmith

Respuesta

19

La biblioteca Audiere hace que esto sea extremadamente fácil de hacer. He aquí un programa casi completo de C# para generar el tono DTMF para el botón "1":

AudioDevice device = new AudioDevice(); 
OutputStream tone1a = device.CreateTone(697); // part A of DTMF for "1" button 
OutputStream tone1b = device.CreateTone(1209); // part B 
tone1a.Volume = 0.25f; 
tone1b.Volume = 0.25f; 
tone1a.Play(); 
tone1b.Play(); 
Thread.Sleep(2000); 
// when tone1a stops, you can easily tell that the tone was indeed DTMF 
tone1a.Stop(); 

Para utilizar Audiere en C#, la forma más fácil de poner en marcha es utilizar Harald Fielker's C# binding (que afirma que las obras en Mono y VS; puedo confirmar que funciona tanto en la versión completa de VS2005 como en las versiones Express 2008 de C# y VC++). Tendrá que descargar Win32 Audiere DLL, lib, and header (que están todos en el mismo zip) y tendrá que compilar el enlace C# desde el origen utilizando tanto VC++ como C#.

Uno de los buenos beneficios del uso de Audiere es que las llamadas no son de bloqueo. No tiene que esperar a que tone1a deje de reproducirse antes de iniciar tone1b, lo cual es claramente una necesidad para reproducir tonos complejos. No conozco ningún límite superior en la cantidad de flujos de salida simultáneos que puede usar, por lo que es probable que sea lo que sea que admita su hardware/sistema operativo. Por cierto, Audiere también puede reproducir ciertos archivos de audio (MP3, WAV, AIFF, MOD, S3M, XM, IT por sí mismo, Ogg Vorbis, Flac, Speex con bibliotecas externas), no solo tonos generados puros.

Una posible desventaja es que hay un "clic" ligeramente audible cuando se inicia o detiene un tono individual; no se nota si agrega un tono a un tono ya en reproducción. La solución más fácil que he encontrado para eso es subir o bajar lentamente el volumen del tono cuando enciendes o apagas el sonido, respectivamente. Es posible que tenga que jugar con la velocidad de la rampa para que suene "perfecto".

Tenga en cuenta que Audiere tiene licencia LGPL y que el enlace no tiene ninguna licencia adjunta. Deberá consultar a su equipo legal o tratar de contactar a Harald si desea utilizar su enlace en un producto comercial; o simplemente puedes hacer tu propia encuadernación y evitar la molestia.


@Tom: Dado que no hay una licencia específica adjunta a la biblioteca de Harald, no estoy seguro de las implicaciones de alojarla; sin embargo, creo que al menos puedo darte detalles sobre cómo se configura mi proyecto libaudieresharpglue.

Usando Visual C++ Express 2008, abra bindings/csharp/libaudieresharpglue/vc8.0/libaudieresharpglue.sln. VC++ convertirá automáticamente la solución en una solución VS9.

En otra carpeta, debe tener el paquete Audiere de Sourceforge. Debajo de sus propiedades de proyecto de VC++, vaya a Propiedades de configuración> C/C++> General y asegúrese de tener path/to/audiere-1.9.4-win32/include en sus "Directorios de inclusión adicionales". Luego, en esa misma ventana, vaya a Enlazador> General y asegúrese de tener /path/to/audiere-1.9.4-win32/lib en sus "Directorios de biblioteca adicionales". Luego, debería poder construir el proyecto (preferiblemente en modo Release) y esta salida libaudieresharpglue.dll en su carpeta vc8.0/Release.

A continuación, abra Visual C# Express 2008. Abra bindings\csharp\test\vc8.0\AudiereCSharpTest.sln y deje que convierta la solución. El proyecto debe ser correcto, pero luego obtendrá un error cuando lo ejecute. Esta bien; en su carpeta csharp/test/vc8.0/bin/Release, debe agregar tanto libaudieresharpglue.dll de la solución de VC++ como audiere.dll del paquete de Sourceforge.

Ahora, debería poder construir y ejecutar AudiereCSharpTest. Tenga en cuenta que, de forma predeterminada, #define stream_test no está comentada en la parte superior de AudiereTest.cs, y que hará referencia a un archivo que no está en su disco duro. Simplemente puede comentar que #define y descomentar noise_test o square_test.

Eso debería cubrirlo; si omití algún detalle, espero que sean lo suficientemente pequeños como para que pueda hacerlo por su cuenta :)

+0

Esa es una biblioteca bonita, podría echarle un vistazo más de cerca si NAudio no funcionara para mí. –

+0

Tengo grandes problemas para compilar la parte "libaudieresharpglue.dll" del contenedor. ¿Alguna idea de dónde puedo tomar un binario? –

+0

Lo he aceptado porque obviamente es lo que tengo que hacer. Sin embargo, a pesar de su explicación a prueba de idiotas, todavía no puedo obtener "libaudieresharpglue.dll" para compilar (se detiene en 100 errores). Cuando me enlace, me dice que no puede abrir el archivo de entrada '. \ Release \ audiere.obj' - ¿Hay algo que me falta? –

0

Sí es posible.

Here is a link a un tutorial sobre esto. pero por supuesto esto también utiliza Console.Beep

+0

Por lo que he visto allí, esto también solo puede generar tonos únicos a la vez. – Joey

4

Siempre puede intentar DirectSound ...

+0

¿Tiene un enlace que se refiere específicamente a la generación de tonos complejos con DirectSound? –

+2

En resumen, escribirá los resultados de muchas llamadas a sin() en un buffer de onda, y luego hará que reproduzca ese buffer. – Kylotan

0

La documentación de MSDN no significa que sea claro si Console.Beep es asíncrona o no. Si es así, probablemente puedas disparar tantas llamadas como necesites en rápida sucesión y nadie será más inteligente. Querrá usar la versión que toma una frecuencia y una duración, por supuesto.

+0

Es sincrónico. – Joey

+0

Soy nuevo en C#: ¿las llamadas síncronas pueden acoplarse mediante subprocesos? –

+1

Puede invocar Console.Beep utilizando un nuevo hilo, pero todavía no puede reproducir muchos sonidos a la vez. – twk

3

He estado buscando en NAudio con la vista para crear un programa que emula los comentarios mientras se reproduce una pista de acompañamiento. Hay una publicación en el blog sobre la generación de sine waves at specific frequencies, sospecho que esto podría adaptarse para hacer lo que está buscando.

+0

Este es el más prometedor hasta ahora, pero no he podido obtener más de una frecuencia corriendo juntas. –

+0

Ha intentado utilizar varios subprocesos, la documentación menciona que admite el dispositivo de mezcla de Windows. –

Cuestiones relacionadas