Enviar muestras de audio a la tarjeta de sonido directamente. - Versión para impresión +- Comunidad Gambas-es (https://gambas-es.org) +-- Foro: Gambas (https://gambas-es.org/forum-3.html) +--- Foro: General (https://gambas-es.org/forum-4.html) +--- Tema: Enviar muestras de audio a la tarjeta de sonido directamente. (/thread-1837.html) |
Enviar muestras de audio a la tarjeta de sonido directamente. - paco - 12-01-2025 Hola, Estoy realizando una aplicación de prueba para sintetizar y editar fragmentos de sonido. El resultado final se encuentra en un vector numérico conteniendo los valores de cada una de la muestras. Para escuchar el fragmento de audio lo que hago es exportar este vector (debidamente convertido en una cadena) en un archivo 'wav' y luego importarlo otra vez para reproducirlo. Esto funciona bien. Pero me gustaría poder escuchar el fragmento directamente, sin tener que exportarlo y volverlo a importar. O sea, enviar el vector con las muestras a la tarjeta de sonido directamente. Y ahí es donde estoy estancado. Supongo que no debe ser algo difícil, pero no encuentro la forma. Agradecería cualquier idea al respecto. Muchas gracias. RE: Enviar muestras de audio a la tarjeta de sonido directamente. - vuott - 12-01-2025 (12-01-2025, 11:43)paco escribió: El resultado final se encuentra en un vector numérico conteniendo los valores de cada una de la muestras.Hola, un vector (array) numérico de que tipo (Byte, Short, ...) ? RE: Enviar muestras de audio a la tarjeta de sonido directamente. - paco - 13-01-2025 Integer (entero con signo). RE: Enviar muestras de audio a la tarjeta de sonido directamente. - vuott - 13-01-2025 ...Integer..... que raro ! Porqué Integer ? Generalmente se utiliza el tipo Short...... resolución de audio de 16 bits. Sin embargo, un modo implica el uso de los recursos del Componente gb.media. Este modo implica tambien la creación de un archivo de soporte a partir de datos vectoriales de tipo Integer[] Código: Public Sub Main() RE: Enviar muestras de audio a la tarjeta de sonido directamente. - paco - 13-01-2025 Muchas gracias. Esto es exactamente lo que buscaba. Es cierto, con short es mejor... RE: Enviar muestras de audio a la tarjeta de sonido directamente. - vuott - 13-01-2025 (13-01-2025, 17:07)paco escribió: Es cierto, con short es mejor...También puedes usar un array de tipo Byte[]. Sin embargo, si no quieres usar el archivo temporaneo de soporte, y queires enviar los datos de audio directamente a la tarjeta de sonido, deberías utilizar las funciones externas de ALSA. En general: https://www.gambas-it.org/wiki/index.php/La_gestione_dell%27audio_e_dei_file_audio_mediante_le_funzioni_esterne_del_API_di_ALSA RE: Enviar muestras de audio a la tarjeta de sonido directamente. - paco - 15-01-2025 Muchas gracias Vuot, ha resultado muy útil tu aportación. Creo que con un array tipo 'Byte' perdería mucho la resolución. Con 'Short' queda bien. La solución 'gb.media' funciona bien, pero hay que exportar un fichero auxiliar para luego volver a importarlo, que es lo que quería evitar. Lo que parece mejor es la API de ALSA. Todavía tengo que trabajar mas con esto, pero ya he conseguido que suene. Ahora tengo que afinarlo (por ejemplo, para que suene en estéreo, con dos canales de audio). Esto es un ejemplo del código con la API de ALSA. Es una implementación muy simple, pero funciona. Cualquier idea de mejora será bienvenida: 'array con las muestras de audio private xondaL as new short[] 'frecuencia de muestreo private fmuestreo as integer = 44100 'librera API de ALSA Library "libasound:2.0.0" Private Const device As String = "default" Private Const SND_PCM_STREAM_PLAYBACK As Integer = 0 Private Const SND_PCM_FORMAT_S16_LE As Byte = 2 Private Const SND_PCM_ACCESS_RW_INTERLEAVED As Integer = 3 Private Extern snd_pcm_open(pcm As Pointer, name As String, pcm_stream As Integer, mode As Integer) As Integer Private Extern snd_pcm_set_params(pcm As Pointer, formatI As Integer, accesso As Integer, channels As Integer, rate As Integer, soft_resample As Integer, latency As Integer) As Integer Private Extern snd_pcm_writei(pcm As Pointer, buffer As Short[], size As Integer) As Integer Private Extern snd_strerror(errnum As Integer) As String Private Extern snd_pcm_close(pcm As Pointer) '--------- 'Aquí va la aplicación para generar las muestras de audio '--------- Public Sub AlsaPlay() Dim err, frames As Integer Dim handle As Pointer err = snd_pcm_open(VarPtr(handle), device, SND_PCM_STREAM_PLAYBACK, 0) If err < 0 Then Error.Raise("Error en la apertura del sub-sistema PCM: " & snd_strerror(err)) err = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, fmuestreo, 1, 500000) If err < 0 Then Error.Raise("Error en los parmetros del sub-sistema PCM: " & snd_strerror(err)) frames = snd_pcm_writei(handle, xondaL, xondaL.Length) If frames < 0 Then Error.Raise("Error en la funcion 'snd_pcm_writei' !") snd_pcm_close(handle) End |