Esta página está en construcción: perdonen los errores, repeticiones y temas inacabados.
This page is being developed: I am sorry for errors, duplications and unfinished subjects.
Entrada de sonido en Visual Basic (incluido en conversaciones con Enrique Tomás)
En Visual Basic se definen variables de todo tipo, números, letreros, arrays o vectores, estructuras que incluyen uno o varios de los tipos anteriores, etc. Pero estos son como nombres privados de Basic que no tienen existencia en un mundo más amplio, como el de Windows, de manera que resulta difícil pero indispensable conectar ambos mundos, cuando alguien quiera ampliar las propiedades de VBasíc con las llamadas de Windows, como las API (Application Programming Interface).
Estas API son extraordinariamente sensitivas a la menor incorrección o descortesía y se cierran como la mimosa o el puercoespín. Las funciones y subrrutinas (las funciones devuelven un valor al ejecutarse, las subrrutinas no, sólo hacen algo) a llamar en este orden para grabar señal de sonido en memoria y recuperarla son:
waveInGetNumDevs Lib "winmm.dll" () As Long
waveInGetDevCaps Lib "winmm.dll" Alias "waveInGetDevCapsA" (ByVal uDeviceID As Long, lpCaps As WAVEINCAPS, ByVal uSize As Long) As Long
waveInOpen Lib "winmm.dll" (lphWaveIn As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMAT, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
waveInPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
waveInStart Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
waveInReset Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
waveInStop Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
waveInUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Y asimismo son necesarias algunas funciones para usar la memoria donde se guarda la señal muestreada.
GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long GlobalFree Lib "kernel32" (ByVal hMem As Long) As LongY sobre todo, estas perlas que permiten conectar los dos mundos de los que hablábamos
CopyStructFromPtr Lib "kernel32" Alias "RtlMoveMemory" (struct As Any, ByVal ptr As Long, ByVal cb As Long) CopyPtrFromStruct Lib "kernel32" Alias "RtlMoveMemory" (ByVal ptr As Long, struct As Any, ByVal cb As Long)Describámoslas en cristiano:
WaveInGetNumDevs. Es la función que accede a la información que tiene el sistema operativo ( o sea, Windows en nuestro caso) acerca de los dispositivos periféricos de audio operativos, y nos devuelve el número de ellos que son capaces de soportar entrada de audio.
waveInGetDevCaps. Es una función que accede a la información que el driver (o sea, ) de la tarjeta de sonido nos presta, y nos devuelve una estructura (variable mixta que incluye otras, sus campos, en su interior, digamos) de datos llamada WAVEINCAPS, en la que podemos encontrar información sobre el nombre, versión, capacidades, etcétera, accediendo a sus campos.
waveInOpen. Una vez que tenemos información sobre la tarjeta de sonido, hemos de tratarla al más estilo UNIX, es decir, vamos a identificarla a partir de ahora con un manejador. ¿Qué es un manejador? En realidad, no es más que un número con el que el sistema va a identificar a partir de ahora un descriptor de fichero abierto, es decir, un número que identifica plenamente al dispositivo.
Por ejemplo, esta rutina
CopyStructFromPtr senales(indi).senal(0), inHdr(indi).lpData, longitud_muestreo_bytes
copia longitud_muestreo_bytes los bytes ocupados por el muestreo, en una estructura de señales, es decir, varias señales unidas e indexadas. La rutina pasa la posición de la señal muestreada en el principio de una de las señales indexadas. El índice permite disponer de dos buffer que se alternan, de modo que mientras el conversor muestrea, el programa puede procesar la señal muestreada anteriormente.
Atención: como los conversores suelen codificar la señal en valores enteros positivos, puede ser necesario llevar esos valores a enteros con signo, es decir, restar a cada muestra la mitad del ámbito. Para un byte, 8 bits, restar 128. Para 2, 16 bits, 32000 y pico.
Veamos una implementación de estas rutinas con una interesantísima cualidad: funciona.
'TIPO DE SENAL '1. reservo memoria para muestrear
hMem = GlobalAlloc(&H42, longitud_muestreo_bytes) 'moveable
inHdr.lpData = GlobalLock(hMem)
inHdr.dwBufferLength = longitud_muestreo_bytes 'BUFFER_SIZE
'2. muestreo
rc = waveInOpen(hWaveIn, DEVICEID, formato_senal, 0, 0, 0)
rc = waveInPrepareHeader(hWaveIn, inHdr, Len(inHdr)
rc = waveInAddBuffer(hWaveIn, inHdr, Len(inHdr))
rc = waveInStart(hWaveIn)
'=====================================================================
'3. llevo a array para procesar 'BUFFER de BYTES de 0 a 255, cero en 128
CopyStructFromPtr senal(0), inHdr.lpData, longitud_muestreo_bytes
' la señal esta en un buffer para su procesado.' Pasos de muestreo de señal audio para su procesado posterior
Vuelta al Principio Última actualización: Thursday, 21 de February de 2013 Visitantes: