UDF Fallida

Tus preguntas. Algoritmos o Grupos de Comandos formando Programas Escripts.
Responder
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

UDF Fallida

Mensaje por Jonny »

Hola

Pues nada. Después de todo el día con la UDF que prometía aquí:
[ul]http://www.emesn.com/autoitforum/viewto ... f=3&t=2251[/ul]
he desistido, porque requiere una dll, que no está dispuesta a colaborar...

Se trataba, de un motor de reconocimiento de voz (por eso lo de terminar el entrenamiento que no entendía Chefito jejeje) para la que quería hacer una UDF, para que fuera más sencillo manejar, pero no hay manera, pues pasa igual que con el rollo de hacer dlls con VB6, que ya se habló por aquí hace días, aunque no exactamente igual; Se cuelga el AutoIt, cuando la dll devuelve lo que sea que devuelva al llamar a la función IniciarUnitReconeixementDeSons, pero con la diferencia, de que no lo hace siempre, si no, cuando se le pasan determinados parámetros.

Resulta, que a esta función, que según la documentación de la dll ha de ser la primera que se llame, antes que ninguna otra, recibe tres parámetros:

- Handle de la ventana del programa cliente.
- Número de sonidos a reconocer.
- Sonidos a reconocer en un string, separándolos por comas si hay más de uno.
(Admite un máximo de 32 sonidos).

Entonces, yo hago algo como:

Código: Seleccionar todo

DllCall("ficherodll.dll", "int", "IniciarUnitReconeixementDeSons", "hwnd", $Handle, "int", 1, "str", "Hola")
Y todo va bien, salvo que la dll no devuelve 0, que es lo que devería devolver para indicar que todo fue bien, pero AutoIt no se cuelga.

En cambio, si hago esto otro:

Código: Seleccionar todo

DllCall("ficherodll.dll", "int", "IniciarUnitReconeixementDeSons", "hwnd", $Handle, "int", 2, "str", "Hola,Adios")
Parece que la función llega a ejecutarse (lo se porque al llamar a la dll esta muestra una gui), pero a la hora de devolver algo, es cuando AutoIt casca, y salta el informe de errores de Windows, etc etc.

Ya he probado con toooodos los tipos posibles, etc, y nada. no se que le pasará a esto.

Adjunto lo que he hecho, por si alguien se anima a investigarlo y si encuentra una solución, prometo terminar la UDF jeje.

El .rar contiene los siguientes archivos:

- Speech_Recognition_UDF.au3: La UDF para interactuar con la dll.
- Speech_Recognition_UDF_Example.au3: El script de ejemplo para utilizar la dll.
- TotiPMSpeechRecognitionEngine.dll: La dll para el reconocimiento de voz.
- Manual Toti Pm Speech Recognition Engine Software Development Kit.doc: La documentación de la dll.

Salu2!
Adjuntos
Speech Recognition AutoIt.rar
(218.85 KiB) Descargado 147 veces
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: UDF Fallida

Mensaje por Ximorro »

A ver si esa DLL está hecha con un VB viejo... ;-)
Ciertamente que la dll sea vieja (de 1999 en el manual) es un problema, puede que ya no funcione... ¿Los ejemplos que vienen con ella en Delphi y VB funcionan?
Otra cosa, parece que la dll es de una versión más moderna que la que comenta en el manual, a ver si ha cambiado algo...

He mirado un poco pero no sé, además es que haces algunas cosas raras, aunque puede que eso no afecte a la dll...
Por ejemplo esos Return que hay en el programa principal son erróneos, los Return se usan dentro de funciones.
Haces un GUIDelete() cuando no hay ningún GUI (en realidad te está devolviendo un error, aunque no lo capturas)

Hay otras cosas más inocuas, pero:
¿Seguro que quieres poner esos estilos al GUI?
$GUI_SS_DEFAULT_GUI ya incluye $WS_CAPTION
$WS_EX_TOPMOST es un estilo extendido, va en el siguiente parámetro. En realidad esto no es tan inocuo porque esa variable tendrá un valor, y estás poniendo el estilo normal que coincide numéricamente con ese estilo extendido, así que algo está haciendo...

Ja, ja, ¿por qué pones tantos #include? Hombre ve poniendo según te hagan falta, así las compilaciones serán más rápidas, el ejecutable más pequeño...

No hace falta que manejes los eventos de minimizar, restaurar y maximizar, con las opciones por defecto resulta que AutoIt ya maneja esos eventos, eso se controla con la opción GUIEventOptions. Huuuuum, creo que voy a ponerlo en cierto tutorial, eso no lo puse y podría confundir. Si los has hecho por leer aquéllo lo siento, mea culpa.

Por favor, indenta el código, es muy difícil seguirlo, por ejemplo SpeechRecognitionStart hay tanto If, Else y EndIf ¡que no se sabe cuál va con cuál! ¿No se ve mejor así?

Código: Seleccionar todo

Func SpeechRecognitionStart($WinHand, $MaxSdRecognition, $SdRecognitionValues)
	If ($WinHand == "" Or $MaxSdRecognition > 32) Then
		Return -1
	EndIf
	$SdRecognitionValues = StringReplace($SdRecognitionValues, ", ", ",")
	$StrDiv = StringSplit($SdRecognitionValues, ",")
	If $MaxSdRecognition <> $StrDiv[0] Then
		Return -1
	EndIf
	$SpeechRecognitionHand = DllOpen($SpeechRecognitionPath)
	If $SpeechRecognitionHand == -1 Then
		Return -1
	Else
		$SpeechRecognitionCallDll = DllCall($SpeechRecognitionHand, "int", "IniciarUnitReconeixementDeSons", "hwnd", $WinHand, "int", $MaxSdRecognition, "str", $SdRecognitionValues)

		If @error <> 0 Then
			Return -1
		Else
			MsgBox(0, "", $SpeechRecognitionCallDll[0])
			Exit

			If $SpeechRecognitionCallDll[0] <> 0 Then
				Return -1
			Else
				Return $SpeechRecognitionCallDll[0]
			EndIf
		EndIf
	EndIf
EndFunc   ;==>SpeechRecognitionStart
He cambiado "HANDLE" por "hwnd", igual es por la versión de AutoIt, aún uso la 3.3.
Por cierto, supongo que es por las pruebas pero dentro de la función de la UDF haces un msgbox y un exit si hay error.

He hecho algunas pruebas y no hay manera, ¿esa dll no estará hecha en VB? O simplemente que es demasiado vieja y con estos Windows no se lleva muy bien.
Mira lo de los ejemplos esos en VB y Delphi...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: UDF Fallida

Mensaje por Jonny »

Hola

Justo, lo de que la dll esté hecha en VB antiguo fue lo primero que se me ocurrió, al ver que cascaba el AutoIt, porque me vino como un rayo la creación de dlls en VB a la cabeza, ja, ja, ja, pero por lo que pone en la documentación, más bien al final, parece que esté hecha en Delphi:
2-La tornada d'una Dll escrita en DELPHI de paràmetres tipus string no funciona correctament. No tinc ni idea de per què. Espero que la propera versió tingui aquest problema resolt. Si el programa client està escrit en un altre llenguatge, com és aquest cas, aquest retorn encara menys. És possible que aquesta solució la canviem en properes versions d'aquest SDK.
¿No?.

De todas maneras, esa función en concreto, parece que no debería devolver ninguna cadena, que era con lo que fallaba el VB, de estar hecha en ese lenguaje, y lo que entiendo que falla en Delphi (en la versión de entonces), si estuviera hecha en ese otro.

Lo mejor de todo, es que he buscado por google, y no hay forma. no encuentro nada que tenga remótamente que ver con esa dll (no se ni como la encontré)...
Quería ver si encontraba alguna versión más nueva de la dll, algo de documentación, comentarios en foros ... pero ni rastro de la dll, y la página donde pone en el manual que habrían actualizaciones no funciona tampoco.

Lo que comentas de esas "cosas raras"; - Los returns, acostumbro a ponerlos en swuitchs y selects, porque una vez me pasó que misteriosamente, se ejecutaba todo el bloque de un select y así fue como lo arreglé, jejeje.
- El GuiDelete() y los estilos, no, era por hacer la interfaz que parece por lo que vi en la documentación, que era obligatoria para probar la dll (por lo del mensaje que envía a la aplicación al terminar el entrenamiento). El GUICreate() que he puesto, es copiado de un Script que vi hace mucho tiempo en el foro inglés, y como esto era por necesidad... de prisa y corriendo, de ahí lo cogí, mismamente.
- Jejeje. Lo de los includes, otro trauma con autoIt; Con las nuevas versiones, no me aclaro nunca con las constantes de las funciones GUI, que están en varias librerías, así, que ¿Solución?: Incluir todas las librerías donde puedan haber constantes y me curo en salud jaja.

Vaya, lo de que AutoIt manejara por defecto los eventos de cerrar, minimizar y maximizar no lo sabía... Siempre he visto manejarlos en todos los scripts, al menos el de cerrar, y por eso hacerlo yo también jejeje.

Sorry, Como digo tanto la UDF como el programa de ejemplo lo hice a la lijera, para ver si era posible trabajar con esa dll, porque algo me decía (en realidad un amigo que también le da al autoit), que no iría... Así, que está todo de cualquier manera, sin indentar incluso. Pensaba hacerlo al terminarlo, pero tendría que haberlo hecho en lo que subí ayer.
Exacto, perdona también por no haber quitado los "MsgBox()" y "Exit", eran para intentar encontrar el problema, por supuesto, no iban ahí en la función jejeje.

No se me ocurre que le puede pasar a la dll, quizá lo que dices de que no se lleve bien con estos Windows sea cierto pero ¿en el 99 no había XP?... Hum, creo que no, jajaja.

Por cierto, sí; tanto los ejemplos en Delphi como en VB que venían con la dll compilados, funcionan bien.
Por eso no termino de entender que puede estar pasando, si la función debería devolver un entero, funciona con Delphi y VB, y lo mejor, pasándole un sonido únicamente funciona.

La alternativa que finalmente estoy planteándome, es ...

Un reconocimiento de voz ¡escrito en autoit!

No parece ser muy complicado (lo básico de reconocer una palabra), aunque segurísimo que al ponerse a escribirlo da mil y un problemas, pero la idea de por donde empezar la tengo...

Y es que, me lo imaginaba mucho más complicado, pero viendo como funcionan algunos softwares de reconocimiento de voz, todos coinciden en el "Entrenamiento", que no es más que una fase del programa, donde has de decir una serie de palabras, letras, frases.... que el programa almacenará, para más tarde, cuando el usuario diga algo, compararlo con esos patrones pregrabados anteriormente. Si coincide con alguno de ellos, se muestra el texto al que está asociado dicho patrón.
Estoy buscando como capturar lo que entra por el micrófono. Tengo un código en VB que parece hacerlo (con apis como no), falta entenderlo... jejeje. Y por lo demás, supongo que sabría comparar lo que capture el micro con un patrón pregrabado.

Lo que no me convence de hacer esto, es que hay que tratar bits y más bits (para hacer un software medio decente), porque no es que se me de muy bien eso de manipular los bits directamente...
A ver que sale al final...

Salu2!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: UDF Fallida

Mensaje por Ximorro »

Ese fragmento del manual que pones es muy interesante no sólo por lo de saber que está en Delphi, sino porque nos está diciendo ¡que tiene problemas con las DLL y los String!. Él comenta sobre la devolución de la función, pero quizás problemas parecidos están fastidiándonos en los parámetros.

Da igual que sea VB o Delphi: problemas con los String y las DLL, sospechoso... Quiero pensar que es porque se trata de compiladores viejos, y que ahora esas cosas estarán solucionadas. Pero claro, a la hora de usar DLLs antiguas desde sistemas nuevos es un problema...

Ay los String y las DLL, igual son las DLL las que no usan un método muy estándar, aunque lógicamente los compiladores que hagan DLLs tendrían que saberlo y actuar en consecuencia...

Pues no, el Return no lo uses para eso, tendrías mal puesta la estructura del Select o Switch y no entraba donde creías o querías que fuera. Solución (o al menos ayuda): Indentación de código :smt003
La indentación no es algo a poner al final para que otros lo puedan ver bien, es una técnica muy útil mientras estás desarrollando para que tú mismo sepas en cada momento dentro de qué función, bucle o condiconal estás. Pruébalo y verás como te sientes más cómodo, como que tienes más control del código.

Se solucionó de casualidad, porque en comprobador de sintaxis suelta un error bien claro si usas un Return en el código principal:
D:\Programacion\AutoIt\miprograma.au3(22,7) : ERROR: 'Return' not allowed from global scope.
Solución: USA SCITE :smt003

Ojo que el GUIDelete y el WS_EX_TOPMOST en los estilos estándar ¡son errores! Si lo has copiado has ido a copiar de uno que estaba mal. Pero es que es mucho más fácil: no borrar un GUI que no existe, no cambiar estilos del formulario ¿exige algún estilo la librería?
Si exige el topmost (que no creo), ponlo después:
$WinHandle=GuiCreate($FileName, 600, 500, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX), $WS_EX_TOPMOST)
El COMPOSITED también es un error tenerlo ahí, pero no te hace falta. El MAXIMIZEBOX sí hay que añadirlo si lo deseas porque no está en el Default. Si no te hace falta se simplifica:
$WinHandle=GuiCreate($FileName, 600, 500, -1, -1, -1, $WS_EX_TOPMOST)
Que por cierto, el TOPMOST se puede poner con una función, WinSetOnTop, así que aún puede quedar así:
$WinHandle=GuiCreate($FileName, 600, 500)
WinSetOnTop($WinHandle,"",1)


Lo de las librerías puedes tenerlas comentadas e ir añadiendo las que hagan falta.
Además ¿Has visto el contenido de GUIConstants.au3? Te lo pongo aquí:
#include <GUIConstantsEx.au3> :smt003

Conclusión, sólo te hacen falta 4:
#Include <Speech_Recognition_UDF.au3>
#Include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>
#Include <StaticConstants.au3>

Las otras 5 te sobran. A veces no siempre está claro qué UDF/librería hace falta, pero buscando en la ayuda la función o constante no reconocida puedes averiguarlo. Creo que conviene no poner librerías innecesarias por lo que te digo que hace el código innecesariamente largo.

Lo de los eventos fíjate que si siempre has visto alguno es el de cerrar ¡los otros seguro que no! De todas maneras ha sido muy interesante que lo pongas porque ahora ya lo sabes (¡a partir de ahora no lo pongas!), y a mí me ha venido bien para decidirme a ampliar el tutorial por si alguien se confundía también con eso.

De todas maneraaaaaaaaas, no analicé mucho el código de eso, me centré más en lo de la DLL... ¡pero no haces nada!. Asignar el valor de los eventos a variables que luego no usas no tiene ninguna función. ¡Esos copy-paste! Tienes que hacer más código propio y menos copy-paste, aprenderás más. De verdad, haces mucho copy-paste pero no te fijas en lo que hace, y a veces está mal o parece que hace algo pero no es así...

Lo de "MsgBox()" y "Exit" no es problema, esas cosas son normales mientras se prueban cosas (yo me suelo poner unos cuantos ConsoleWrite para ver qué está haciendo el programa). Sólo te lo comentaba por si se te había pasado quitarlo y luego te daba problemas.

Lo de la DLL lo veo chungo... esos problemas con strings... En el 99 acababa de salir el 98, aún tenía que llegar la revolución de los unicode, que estaba en pañales, ahora ya está muy implantado y tenemos el maravilloso cacao del ANSI/UNICODE pegándose por todas partes... :smt001

Interesante que los ejemplos VB y Delphi vayan. Puede ser porque ¡ellos lo hacen mal! Hacerlo mal quiere decir que lo hacen igual que la DLL, con lo que entre ellos no tienen problemas. Quizás actualmente las cosas son diferentes, AutoIt supongo que usa la especificación moderna, que no será tan compatible con aquélla. Desde luego otra posibilidad es que haya algún problema en el diseño de AutoIt, pero me resisto a creerlo, la API va perfectamente y parece que estas cosas sólo pasan con DLLs hechas en compiladores "viejos".

¡Suerte con lo de hacerlo en AutoIT!
La verdad es que te metes siempre con cosas demasiado complejas, pero en fin.
Creo que los programas que entrenan para aprender sonidos (o escritura) no guardan necesariamente todas las muestras (eso ocuparía una barbaridad) sino que las analiza para buscar patrones que identifiquen similaritudes o distingan palabras distintas entre sí...

Lo del micrófono me suena haberlo visto por el foro, usando el media player, de hecho me suena haber visto cómo grabarlo en mp3. Búscalo y si no lo encuentras me lo dices, igual estaba en el foro inglés, echaré un vistazo.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: UDF Fallida

Mensaje por Jonny »

Hola

Pues tiene toda la lógica lo que dices, de la incompatibilidad de las dll creadas con compiladores viejos y los sistemas operativos de ahora, debe ser ese el problema y no se yo si habrá solución (quizá con esa opción del XP de compatibilidad con programas antiguos), que no se exactamente como se llama, la vi hace mucho tiempo por entre las opciones de las propiedades del sistema, o algo así...
Pero no se si eso ayudaría, ni como usarlo programando, porque decirle al usuario que tiene que tener activa esa opción, o ejecutar el programa desde ella... :).

La librería no exige ningún estilo. Copié esa GUI y la verdad es que no la entiendo muy bien, con el BitAnd y todo lo que tiene... Es cierto lo de copiar código, no es bueno copiar código que no sabes exactamente qué hace, porque luego pasan estas cosas :), que está mal y no lo sabes pero ¡como iba a pensar que alguien que ha hecho un Script en el foro inglés lo iba a hacer mal! jejeje.

Buena idea la de comentar las librerías y descomentar las que realmente necesite, no había caído en ese truquillo.

No entiendo cuando dices:
Creo que los programas que entrenan para aprender sonidos (o escritura) no guardan necesariamente todas las muestras (eso ocuparía una barbaridad) sino
que las analiza para buscar patrones que identifiquen similaritudes o distingan palabras distintas entre sí...
Esos patrones han de estar guardados en algún sitio ¿no?.

Yo pensaba, que cuando un programa de reconocimiento de voz en la fase de entrenamiento te dice que digas X palabra o frase, es para tenerla como patrón con el que comparar en la fase de reconocimiento.
Desde luego, lo suyo sería que reconociera lo que se dice sin entrenamiento, pero eso sí que lo veo chungo chungo...

Lo del micrófono, he visto algo como lo que dices en una udf en el foro inglés; que de paso os copio, por si a alguien le interesa, ya que tiene varias funciones multimedia.
La copio, porque no tengo el link:

Código: Seleccionar todo

;===============================================================================
;
; Function Name:    _MediaOpen()
; Description:      Opens a media file.
; Parameter(s):     $s_location     - Location of the media file
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns Media ID needed for the other media functions
;                   On Failure - Returns 0  and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaOpen($s_location, $h_guihandle = 0)
	If Not IsDeclared("i_MediaCount") Then Global $i_MediaCount=0
	$i_MediaCount=$i_MediaCount+1
	DllCall("winmm.dll","int","mciSendString","str","open "&FileGetShortName($s_location)&" alias media"&String($i_MediaCount),"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return String($i_MediaCount)
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaCreate()
; Description:      Creates a new media for recording, capturing etc.
; Parameter(s):     $s_format     - Format of the file.
;                   0 = CD Audio
;                   1 = Digital video
;                   2 = Overlay
;                   3 = sequencer
;                   4 = Vcr
;                   5 = Video disc
;                   6 = Wave Audio
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns Media ID needed for the other media functions
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaCreate($s_format)
	If Not IsDeclared("i_MediaCount") Then Global $i_MediaCount=0
	$i_MediaCount=$i_MediaCount+1
	If $s_format=0 Then
		$s_Use="cdaudio"
	ElseIf $s_format=1 Then
		$s_Use="digitalvideo"
	ElseIf $s_format=2 Then
		$s_Use="overlay"
	ElseIf $s_format=3 Then
		$s_Use="sequencer"
	ElseIf $s_format=4 Then
		$s_Use="vcr"
	ElseIf $s_format=5 Then
		$s_Use="videodisc"
	ElseIf $s_format=6 Then
		$s_Use="waveaudio"
	EndIf
	DllCall("winmm.dll","int","mciSendString","str","open new type "&$s_Use&" alias media"&String($i_MediaCount),"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return String($i_MediaCount)
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaPlay()
; Description:      Plays a opened media file.
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   [optional] $i_From        - Sets time in seconds where to begin playing
;                   [optional] $i_To          - Sets time in seconds where to bstop playing
;                   [optional] $i_Speed       - Sets the speed to play with
;                   [optional] $f_Fast        - When 1 it will play faster then normal
;                   [optional] $f_Slow        - When 1 it will play slower then normal
;                   [optional] $f_Fullscreen  - When 1 movies will play fullscreen
;                   [optional] $f_Repeat      - When 1 it will keep repeating
;                   [optional] $f_Reverse     - When 1 the movie will been played reversed
;                   [optional] $f_Scan        - When 1 plays as fast as possible
;                   The default value of all the optional parameters is 0.
;                   Some file formats dont understand some of the optional functions
;                   Experimate with it.
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaPlay($i_MediaId,$i_From = 0,$i_To = 0,$i_Speed = 0,$f_Fast = 0,$f_Slow = 0,$f_Fullscreen = 0,$f_Repeat=0,$f_Reverse=0,$f_Scan = 0)
	$s_Parameters=""
	If $i_From Then $s_Parameters=$s_Parameters&" from "&$i_From
	If $i_To Then $s_Parameters=$s_Parameters&" to "&$i_To
	If $i_Speed Then $s_Parameters=$s_Parameters&" speed "&$i_Speed
	If $f_Fast Then $s_Parameters=$s_Parameters&" fast"
	If $f_Fullscreen Then $s_Parameters=$s_Parameters&" fullscreen"
	If $f_Repeat Then $s_Parameters=$s_Parameters&" repeat"
	If $f_Reverse Then $s_Parameters=$s_Parameters&" reverse"
	If $f_Scan Then $s_Parameters=$s_Parameters&" scan"
	If $f_Slow Then $s_Parameters=$s_Parameters&" slow"
	DllCall("winmm.dll","int","mciSendString","str","play media"&$i_MediaId&$s_Parameters,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaRecord()
; Description:      Records from a microphone
;                   Stop recording with _MediaStop()
;                   (choose position with _MediaSeek())
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaRecord($i_MediaId)
	DllCall("winmm.dll","int","mciSendString","str","record media"&$i_MediaId,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaCut()
; Description:      Cuts a specified part of the movie to the clipboard.
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   $i_From        - From time in seconds
;                   $i_To          - To time in seconds
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaCut($i_MediaId,$i_From,$i_To)
	DllCall("winmm.dll","int","mciSendString","str","cut media"&$i_MediaId&" from "&$i_From&" to "&$i_To,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaCopy()
; Description:      Copies a specified part of the movie to the clipboard.
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   $i_From        - From time in seconds
;                   $i_To          - To time in seconds
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaCopy($i_MediaId,$i_From,$i_To)
	DllCall("winmm.dll","int","mciSendString","str","copy media"&$i_MediaId&" from "&$i_From&" to "&$i_To,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaPaste()
; Description:      Paste media from the clipboard.
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaPaste($i_MediaId,$i_From,$i_To)
	DllCall("winmm.dll","int","mciSendString","str","paste media"&$i_MediaId,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaDelete()
; Description:      Deletes a specified part of the movie.
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   $i_From        - From time in seconds
;                   $i_To          - To time in seconds
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaDelete($i_MediaId,$i_From,$i_To)
	DllCall("winmm.dll","int","mciSendString","str","delete media"&$i_MediaId&" from "&$i_From&" to "&$i_To,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaCapture()
; Description:      Copies the contents of the frame buffer and stores it in the
;                   specified file.
;                   Stop recording with _MediaStop()
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   $s_Location    - Location where to store the file.
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaCapture($i_MediaId,$s_Location)
	DllCall("winmm.dll","int","mciSendString","str","capture media"&$i_MediaId&" "&FileGetShortName($s_Location),"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaStop()
; Description:      Stops playing/recording of a Media ID
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaStop($i_MediaId)
	DllCall("winmm.dll","int","mciSendString","str","stop media"&$i_MediaId,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaSeek()
; Description:      Moves to a specified Position and stops.
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   $i_Position    - Position in seconds to move to, -1 goes to start
;                   -2 goes to end
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaSeek($i_MediaId,$i_Position)
	If $i_Position = -1 Then
		$s_Position = "end"
	ElseIf $i_Position = -2 Then
		$s_Position = "begin"
	Else
		$s_Position = String($i_Position)
	EndIf
	DllCall("winmm.dll","int","mciSendString","str","seek media"&$i_MediaId&" to "&$s_Position,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaPause()
; Description:      Pauses playing/recording of a Media ID
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaPause($i_MediaId)
	DllCall("winmm.dll","int","mciSendString","str","pause media"&$i_MediaId,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaResume()
; Description:      Resumes playing/recording of a Media ID
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaResume($i_MediaId)
	DllCall("winmm.dll","int","mciSendString","str","resume media"&$i_MediaId,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaSave()
; Description:      Saves a opened Media ID to the selected file
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
;                   $s_Location    - Location to save to (must be full path)
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaSave($i_MediaId,$s_Location)
    DllCall("winmm.dll","int","mciSendString","str","save media"&$i_MediaId&" " & '"'&FileGetShortName($s_Location)&'"',"str","","int",65534,"hwnd",0)
    If @error Then
        SetError(1)
        Return 0
    Else
        Return 1
    EndIf
EndFunc
;===============================================================================
;
; Function Name:    _MediaClose()
; Description:      Closes a existing Media ID
; Parameter(s):     $i_MediaId     - Media ID returned by _MediaOpen()/MediaCreate()
; Requirement(s):   AutoIt
; Return Value(s):  On Success - Returns 1
;                   On Failure - Returns 0 and sets @ERROR = 1
; Author(s):        svennie
;
;===============================================================================
Func _MediaClose($i_MediaId)
	DllCall("winmm.dll","int","mciSendString","str","close media"&$i_MediaId,"str","","int",65534,"hwnd",0)
	If @error Then
		SetError(1)
		Return 0
	Else
		Return 1
	EndIf
EndFunc
Lo de capturar el micrófono, imagino que sería concretamente esto de la función "_MediaRecord":

Código: Seleccionar todo

	DllCall("winmm.dll","int","mciSendString","str","record media"&$i_MediaId,"str","","int",65534,"hwnd",0)
Pero no comprendo muy bien como usan esta api. He estado buscando la documentación y encontré esto:
[ul] http://www.solotuweb.com/fs~id~8844.html [/ul]

Pero en el código que pongo más arriba de la UDF, hacen una llamada diferente a como explican en esa web que funciona la api.

Por ejemplo, el primer parámetro, parece que es un buffer donde se almacena lo que se va capturando del micrófono (si no he entendido mal, que mi inglés es bastante malo :)), y en la UDF no pasan ningún bufer, por lo que ¿Dónde se almacena lo que se recoge del micro con esa llamada?
Además, imagino que debería pasarse un puntero al buffer y no un string como pone ahí...

El segundo parámetro, creo que la explicación quiere decir, que hay que pasar el tamaño del buffer ¿Verdad?. Pues si es así, no entiendo que pasen 65534, cuando no se refieren a ningún buffer en el parámetro anterior ... Y el último parámetro, pues ni idea de que será; Un handle, pero ¿De qué? :).

En fin, que debe hacerse con la función "mciSendString", pero no se bien cómo.

En otra función de la UDF (_MediaCapture()), parece que capturan también lo que entra por el micrófono, pero en esta función lo graban en un fichero y eso en principio no me interesaría, pues imagino que sería más sencillo tratar lo que se reciba del micrófono tal cual, que convertido a un formato concreto.
Según me digeron, cuando se recibe algo del micro, estaría en RAW y eso sería más fácil de tratar que WAV, MP3 etc (de eso no tengo ni idea :)). Así qué, si es así, imagino que me interesa el código de la primera función que decía ("_MediaRecord").

Salu2!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: UDF Fallida

Mensaje por Ximorro »

¡Mal no, estaba fatal! Pues vaya código fuiste a copiar, mira que habrá.

Pero el caso es que no tienes que quedarte con el código copiado y ya está, tienes que entenderlo. Esfuérzate en entenderlo y de esa manera también aprenderás (aunque te aseguro que haciendo código por uno mismo se aprende más). Además entendiendo el código copiado no te pasará esto de que se te cuele código incorrecto.

¿Por qué no empiezas por ahí Jonny? Haz programas de entrenamiento, cosas más simples, pero ya ves que hacer un simple GUI es algo que no has practicado. Haz programas más pequeños de entrenamiento, sin APIs complicadas ni DLLs ni cosas de esas. Luego irás luego mucho más rápido y usar UDFs de esas será mucho más fácil.

Lo de las muestras no lo sé a ciencia cierta, es lo que imagino, para entrenarlo hay que hacer muchas muestras, no creo que las guarden todas, (imagínate 100 wavs para cada palabra), guardarán una muestra "tipo", una especie de media de todas las muestras. Luego cuando dices una palabra comparará con todas las "muestras tipo" y se quedará con la que más se parece.
Realmente no sé cómo se realiza exactamente la comparación de ondas, habrá que hacer escalados en amplitud y frecuencia para superponerlas bien antes de comparar (unas veces hablarás más rápido que otras, otras veces tendrás la voz más ronca que otras...) Si no si le pides el café por la mañana con voz de ultratumba no te hará caso, aunque funcione perfectamente por la tarde ;-)

Respecto a la UDF esa, siempre puedes empezar usándola directamente en vez de extraer las funciones, busca ejemplos que la usen. Para eso son las UDF, ya te la dan echa así que para qué complicarse. Otra cosa es que luego, una vez tengas tu programa, te interese hacer una mini-UDF con sólo las funciones que utilizas, entonces estúdiate la UDF para ver cómo hace lo que hace y ver realmente lo que necesita y lo que no...

Es que parece que grabar sea una función y se acabó, pero no, habrá que inicializar el media-player, inicializar el sonido, ponerse a grabar, parar grabación, guardar sonido a disco...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: UDF Fallida

Mensaje por Jonny »

Hola

Puf, menos mal que lo de una UDF de reconocimiento de voz era una vaga idea :).

Será mejor me parece, buscar una dll que funcione mejor que la que pretendía usar, al menos con las funciones Dll de Autoit me voy llevando mejor que antes...

Respecto a las guis, pues gracias a la ayuda traducida de la versión 3.3.6.0, voy entendiendo mejor como funcionan, sobre todo los estilos; Igual que con muchas otras cosas de autoit, que con la ayuda en inglés me enteraba más bien poco :).

- Lo de copiar código a veces es por pereza de escribirlo de cero jejejeje. Pero ya veo, que como dicen; "Lo barato sale caro".... Al final, toca escribir el código dos veces :).

Salu2!
Responder