Reproducción de audio por un canal

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Responder
Avatar de Usuario
Bethory
Mensajes: 13
Registrado: 11 Feb 2009, 20:24

Reproducción de audio por un canal

Mensaje por Bethory »

Buen día:
mi cuestión es lograr reproducir un sonido en "wav" o "mp3" pero solo por el canal derecho o por el izquierdo
saben de alguna función o dll que me pueda ayudar a logra este propósito ??

de antemano muchas gracias
Me gustaría arreglar el mundo.... pero no me han dado el código fuente xD
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Reproducción de audio por un canal

Mensaje por Chefito »

Mmmmm.....hay que intentar buscar un poquito en el foro antes de contestar eehhhh... :smt003 .

Mira este post: http://www.emesn.com/autoitforum/viewto ... 1296#p7600

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Bethory
Mensajes: 13
Registrado: 11 Feb 2009, 20:24

Re: Reproducción de audio por un canal

Mensaje por Bethory »

Gracias por tu atención chefito :smt045
estuve viendo el link al que me remitiste allí entendí que debía utilizar en concreto estas dos funciones para lograr mi propósito

__SoundMciSendString("setaudio " & $aSnd_id & " left volume to " & $volumenizq)
__SoundMciSendString("setaudio " & $aSnd_id & " right volume to " & $volumendcho)

luego de ello agregué una función mas a la librería "sound.au3" en donde utilizo la función que me indicaste

Código: Seleccionar todo

Func _SoundLeftBalance($aSndID, $volumenizq) ;funcion agregada a "sound.au3"
	__SoundMciSendString("setaudio " & $aSndID & " left volume to " & $volumenizq)
EndFunc
mi pregunta radica en saber que valores le debo dar a la variable $aSndID
y que rango de valores soporta la variable $volumenizq

de ante mano muchísimas gracias :smt006
Me gustaría arreglar el mundo.... pero no me han dado el código fuente xD
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Reproducción de audio por un canal

Mensaje por Chefito »

$aSnd_id : Identificador de un sonido (ID del sonido). Esto te lo devuelve la función _SoundOpen cuando cargas un sonido. Para más información mira la función anterior en la ayuda.

Respecto a los volúmenes, creo que todos van comprendidos de 0 a 1000 como dije en su día.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Bethory
Mensajes: 13
Registrado: 11 Feb 2009, 20:24

Mensaje por Bethory »

primero que todo muchísimas gracias a chefito por su valiosa ayuda :smt023

postéo el código por si le sirve a alguna persona

Código: Seleccionar todo

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <SliderConstants.au3>
#include <ProgressConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Sound1.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Reproductor de audio", 341, 160, 423, 554)
GUISetIcon("Shell32.dll", 228);269
$Izq = GUICtrlCreateButton("Izquierdo", 56, 25, 97, 41, 0)
$Der = GUICtrlCreateButton("Derecho", 184, 25, 97, 41, 0)
$Parar = GUICtrlCreateButton("Detener", 118, 83, 97, 41, 0)
$Pos = GUICtrlCreateProgress(0, 130, 341, 10, $PBS_SMOOTH)
$Slider1 = GUICtrlCreateSlider(312, 2, 20, 130, BitOR($TBS_VERT, $TBS_TOP, $TBS_NOTICKS))
GUICtrlSetData(-1, 0)
$Label1 = GUICtrlCreateLabel("00:00:00", 20, 100, 84, 25, $WS_EX_STATICEDGE)
GUICtrlSetFont(-1, 14, 800, 0, "Tahoma")
$filemenu = GUICtrlCreateMenu("&Archivo")
$Abrir = GUICtrlCreateMenuItem("Abrir...", $filemenu)
$propiedades = GUICtrlCreateMenuItem("Propiedades de audio", $filemenu)
$Salir = GUICtrlCreateMenuItem("Salir", $filemenu)
#EndRegion ### END Koda GUI section ###

Opt("TrayIconHide", 1)
$message = "Seleccione un archivo de audio"
$sonido = "no audio"
Global $sound = ""
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit 0
		Case $Abrir
			$sonido = FileOpenDialog($message, @MyDocumentsDir & "\", "Audio (*.wav;*.mp3)", 1)
		Case $Salir
			Exit 0
		Case $Izq
			If _SoundStatus($sound) = "playing" Then
				_SoundStop($sound)
				_SoundClose($sound)
			EndIf
			$sound = _SoundOpen($sonido)
			If @error = 2 Then
				MsgBox(0, "Error", "No fichero(s) escogidos")
			ElseIf @extended <> 0 Then
				$extended = @extended
				$stText = DllStructCreate("char[128]")
				$errorstring = DllCall("winmm.dll", "short", "mciGetErrorStringA", "str", $extended, "ptr", DllStructGetPtr($stText), "int", 128)
				MsgBox(0, "Error", "The open failed." & @CRLF & "Error Number: " & $extended & @CRLF & "Error Description: " & DllStructGetData($stText, 1) & @CRLF & "Please Note: The sound may still play correctly.")
			Else
				ConsoleWrite("Vamos bien =)")
			EndIf
			_SoundLeftBalance($sound, 0)
			_SoundRightBalance($sound, 1000)
			_SoundPlay($sound)
		Case $Der
			If _SoundStatus($sound) = "playing" Then
				_SoundStop($sound)
				_SoundClose($sound)
			EndIf
			$sound = _SoundOpen($sonido)
			If @error = 2 Then
				MsgBox(0, "Error", "No fichero(s) escogidos")
			ElseIf @extended <> 0 Then
				$extended = @extended ;assign because @extended will be set after DllCall
				$stText = DllStructCreate("char[128]")
				$errorstring = DllCall("winmm.dll", "short", "mciGetErrorStringA", "str", $extended, "ptr", DllStructGetPtr($stText), "int", 128)
				MsgBox(0, "Error", "The open failed." & @CRLF & "Error Number: " & $extended & @CRLF & "Error Description: " & DllStructGetData($stText, 1) & @CRLF & "Please Note: The sound may still play correctly.")
			Else
				ConsoleWrite("Vamos bien =)")
			EndIf
			_SoundLeftBalance($sound, 1000)
			_SoundRightBalance($sound, 0)
			_SoundPlay($sound)
		Case $Parar
			_SoundStop($sound)
			_SoundClose($sound)
		Case $propiedades
			ShellExecute("mmsys.cpl")
	EndSwitch
	
	If _SoundStatus($sound) = "playing" Then
		SoundSetWaveVolume(100 - GUICtrlRead($Slider1))
		GUICtrlSetData($Pos, 100 / _SoundLength($sound, 2) * _SoundPos($sound, 2))
		GUICtrlSetData($Label1, _SoundPos($sound, 1))
	Else
		GUICtrlSetData($Pos, 0)
		GUICtrlSetData($Label1, "00:00:00")
	EndIf
WEnd
para agregue un par de funciones a la libreria "sound.au3" las cuales son necesarias para el correcto funcionamiento del programa :smt024

Código: Seleccionar todo

#include-once

#include "File.au3"		; Using: _PathSplit

; #INDEX# =======================================================================================================================
; Title .........: Sound
; AutoIt Version : 3.2 ++
; Language ......: English
; Description ...: Functions that assist with Sound management.
; Author(s) .....: RazerM, Melba23, Simucal, PsaltyDS
; Dll ...........: winmm.dll
; ===============================================================================================================================

; #CONSTANTS# ===================================================================================================================
Global Const $__SOUNDCONSTANT_SNDID_MARKER = 0x49442d2d
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
;_SoundOpen
;_SoundClose
;_SoundPlay
;_SoundStop
;_SoundPause
;_SoundResume
;_SoundLength
;_SoundSeek
;_SoundStatus
;_SoundPos
;_SoundOff
;_SoundLeftBalance
;_SoundRightBalance
; ===============================================================================================================================

; #INTERNAL_USE_ONLY#============================================================================================================
;__SoundChkSndID
;__SoundMciSendString
;__SoundReadTLENFromMP3
;__SoundReadXingFromMP3
;__SoundTicksToTime
;__SoundTimeToTicks
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundOpen
; Description ...: Opens a sound file for use with other _Sound functions
; Syntax.........: _SoundOpen($sFile)
; Parameters ....: $sFile - The sound file
; Return values..: Success      - 3-element array (used as Sound ID)
;                  Failure      - 0 and Sets @error to:
;                  @error     1 - Open failed - @extended holds MCI error code
;                             2 - File does not exist
; Author ........: RazerM, Melba23, some code by Simucal, PsaltyDS
; Modified.......:
; Remarks .......:
; Related .......: _SoundClose, _SoundLength, _SoundPause, _SoundPlay, , _SoundResume, _SoundStatus, _SoundStop
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundOpen($sFile)
	;check for file
	If Not FileExists($sFile) Then Return SetError(2, 0, 0)
	;create random string for file ID
	Local $aSndID[4]
	For $i = 1 To 10
		$aSndID[0] &= Chr(Random(97, 122, 1))
	Next

	Local $szDrive, $szDir, $szFName, $szExt
	_PathSplit($sFile, $szDrive, $szDir, $szFName, $szExt)

	Local $sSndDirName
	If $szDrive = "" Then
		$sSndDirName = @WorkingDir & "\"
	Else
		$sSndDirName = $szDrive & $szDir
	EndIf
	Local $sSndFileName = $szFName & $szExt

	Local $sSndDirShortName = FileGetShortName($sSndDirName, 1)

	;open file
	__SoundMciSendString("open " & FileGetShortName($sFile) & " alias " & $aSndID[0])
	If @error Then Return SetError(1, @error, 0) ; open failed

	Local $sTrackLength, $fTryNextMethod = False
	Local $oShell = ObjCreate("shell.application")
	If IsObj($oShell) Then
		Local $oShellDir = $oShell.NameSpace($sSndDirShortName)
		If IsObj($oShellDir) Then
			Local $oShellDirFile = $oShellDir.Parsename($sSndFileName)
			If IsObj($oShellDirFile) Then
				Local $sRaw = $oShellDir.GetDetailsOf($oShellDirFile, -1)
				Local $aInfo = StringRegExp($sRaw, ": ([0-9]{2}:[0-9]{2}:[0-9]{2})", 3)
				If Not IsArray($aInfo) Then
					$fTryNextMethod = True
				Else
					$sTrackLength = $aInfo[0]
				EndIf
			Else
				$fTryNextMethod = True
			EndIf
		Else
			$fTryNextMethod = True
		EndIf
	Else
		$fTryNextMethod = True
	EndIf

	Local $sTag
	If $fTryNextMethod Then
		$fTryNextMethod = False
		If $szExt = ".mp3" Then
			Local $hFile = FileOpen(FileGetShortName($sSndDirName & $sSndFileName), 4)
			$sTag = FileRead($hFile, 5156)
			FileClose($hFile)
			$sTrackLength = __SoundReadXingFromMP3($sTag)
			If @error Then $fTryNextMethod = True
		Else
			$fTryNextMethod = True
		EndIf
	EndIf

	If $fTryNextMethod Then
		$fTryNextMethod = False
		If $szExt = ".mp3" Then
			$sTrackLength = __SoundReadTLENFromMP3($sTag)
			If @error Then $fTryNextMethod = True
		Else
			$fTryNextMethod = True
		EndIf
	EndIf

	If $fTryNextMethod Then
		$fTryNextMethod = False
		;tell mci to use time in milliseconds
		__SoundMciSendString("set " & $aSndID[0] & " time format miliseconds")
		;receive length of sound
		Local $iSndLenMs = __SoundMciSendString("status " & $aSndID[0] & " length", 255)

		;assign modified data to variables
		Local $iSndLenMin, $iSndLenHour, $iSndLenSecs
		__SoundTicksToTime($iSndLenMs, $iSndLenHour, $iSndLenMin, $iSndLenSecs)

		;assign formatted data to $sSndLenFormat
		$sTrackLength = StringFormat("%02i:%02i:%02i", $iSndLenHour, $iSndLenMin, $iSndLenSecs)
	EndIf

	; Convert Track_Length to mSec
	Local $aiTime = StringSplit($sTrackLength, ":")
	Local $iActualTicks = __SoundTimeToTicks($aiTime[1], $aiTime[2], $aiTime[3])

	;tell mci to use time in milliseconds
	__SoundMciSendString("set " & $aSndID[0] & " time format miliseconds")

	;;Get estimated length
	Local $iSoundTicks = __SoundMciSendString("status " & $aSndID[0] & " length", 255)

	;Compare to actual length
	Local $iVBRRatio
	If Abs($iSoundTicks - $iActualTicks) < 1000 Then ;Assume CBR, as our track length from shell.application is only accurate within 1000ms
		$iVBRRatio = 0
	Else ;Set correction ratio for VBR operations
		$iVBRRatio = $iSoundTicks / $iActualTicks
	EndIf

	$aSndID[1] = $iVBRRatio
	$aSndID[2] = 0
	$aSndID[3] = $__SOUNDCONSTANT_SNDID_MARKER

	Return $aSndID
EndFunc   ;==>_SoundOpen

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundClose
; Description ...: Closes a sound
; Syntax.........: _SoundClose($aSndID)
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen()
; Return values..: Success      - 1
;                  Failure      - 0 and set @error
;                  @error     1 - Close failed
;                             3 - Invalid Sound ID
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundClose($aSndID)
	If Not IsArray($aSndID) Or Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid sound ID

	__SoundMciSendString("close " & $aSndID[0])
	If @error Then Return SetError(1, @error, 0)
	Return 1
EndFunc   ;==>_SoundClose

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundPlay
; Description ...: Plays a sound from the current position (beginning is the default)
; Syntax.........:_SoundPlay($aSndID[, $iWait = 0])
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file
;				   $iWait - If set to 1 the script will wait for the sound to finish before continuing
; Return values..: Success      - 1
;                  Failure      - 0 and set @error
;                  @error     1 - Play failed
;                             2 - Invalid $iWait parameter
;                             3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......: _SoundPause, _SoundStop, _SoundSeek, _SoundOpen, _SoundResume
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundPlay($aSndID, $iWait = 0)
	;validate $iWait
	If $iWait <> 0 And $iWait <> 1 Then Return SetError(2, 0, 0) ; invalid $iWait parameter
	If Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;if sound has finished, seek to start
	If _SoundPos($aSndID, 2) = _SoundLength($aSndID, 2) Then __SoundMciSendString("seek " & $aSndID[0] & " to start")
	;If $iWait = 1 then pass wait to mci
	If $iWait = 1 Then
		__SoundMciSendString("play " & $aSndID[0] & " wait")
	Else
		__SoundMciSendString("play " & $aSndID[0])
	EndIf
	;return
	If @error Then Return SetError(1, @error, 0)
	Return 1
EndFunc   ;==>_SoundPlay

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundStop
; Description ...: Stops the sound
; Syntax.........: _SoundStop(ByRef $aSndID)
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file (must be a variable)
; Return values..: Success    - 1
;                  Failure    - 0 and set @error
;                  @error   1 - Stop failed
;                           3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundStop(ByRef $aSndID)
	; create temp variable so file name variable is not changed ByRef
	Local $vTemp = $aSndID
	If Not __SoundChkSndID($vTemp) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;reset VBR factor if used
	If IsArray($aSndID) Then $aSndID[2] = 0

	;stop
	__SoundMciSendString("stop " & $vTemp[0])
	If @error Then Return SetError(2, @error, 0)
	;seek to start
	__SoundMciSendString("seek " & $vTemp[0] & " to start")
	If @error Then Return SetError(1, @error, 0)
	;return
	Return 1
EndFunc   ;==>_SoundStop

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundPause
; Description ...: Pauses the sound
; Syntax.........: _SoundPause($aSndID)
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file
; Return values..: Success      - 1
;                  Failure      - 0 and sets @error
;                  @error     1 - Pause failed
;                             3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......: _SoundResume, _SoundOpen, _SoundPlay
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundPause($aSndID)
	If Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;pause sound
	__SoundMciSendString("pause " & $aSndID[0])
	;return
	If @error Then Return SetError(1, @error, 0)
	Return 1
EndFunc   ;==>_SoundPause

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundResume
; Description ...: Resumes the sound after being paused
; Syntax.........: _SoundResume($aSndID)
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file
; Return values..: Success      - 1
;                  Failure      - 0 and set @error
;                  @error     1 - Resume failed
;                             3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundResume($aSndID)
	If Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;resume sound
	__SoundMciSendString("resume " & $aSndID[0])
	;return
	If @error Then Return SetError(1, @error, 0)
	Return 1
EndFunc   ;==>_SoundResume

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundLength
; Description ...: Returns the length of the sound in the format hh:mm:ss
; Syntax.........: _SoundLength($aSndID[, $iMode = 1])
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file,
;				   $iMode = 1 - hh:mm:ss, $iMode = 2 - milliseconds
; Return values .: Success      - Length of the sound
;                  Failure      - 0 and set @error
;                  @error     1 - Invalid $iMode parameter
;                             3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......: jpm
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundLength($aSndID, $iMode = 1)
	;validate $iMode
	If $iMode <> 1 And $iMode <> 2 Then Return SetError(1, 0, 0)
	Local $bFile = False
	If Not IsArray($aSndID) Then
		If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file name
		$bFile = True
		$aSndID = _SoundOpen($aSndID)
	Else
		If Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID
	EndIf

	;tell mci to use time in milliseconds
	__SoundMciSendString("set " & $aSndID[0] & " time format miliseconds")
	;receive length of sound
	Local $iSndLenMs = Number(__SoundMciSendString("status " & $aSndID[0] & " length", 255))
	If $aSndID[1] <> 0 Then $iSndLenMs = Round($iSndLenMs / $aSndID[1])

	If $bFile Then _SoundClose($aSndID) ;if user called _SoundLength with a filename

	If $iMode = 2 Then Return $iSndLenMs

	; $iMode = 1 (hh:mm:ss)

	;assign modified data to variables
	Local $iSndLenMin, $iSndLenHour, $iSndLenSecs
	__SoundTicksToTime($iSndLenMs, $iSndLenHour, $iSndLenMin, $iSndLenSecs)

	;assign formatted data to $sSndLenFormat
	Local $sSndLenFormat = StringFormat("%02i:%02i:%02i", $iSndLenHour, $iSndLenMin, $iSndLenSecs)

	;return correct variable
	Return $sSndLenFormat
EndFunc   ;==>_SoundLength

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundSeek
; Description ...: Seeks the sound to a specified time
; Syntax.........:  _SoundSeek(ByRef $aSndID, $iHour, $iMin, $iSec)
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() (must NOT be a file), $iHour, $iMin, $iSec
; Return values..: Success      - 1
;                  Failure      - 0 and set @error
;                  @error     1 - Seek failed
;                             3 - Invalid Sound ID
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundSeek(ByRef $aSndID, $iHour, $iMin, $iSec)
	If Not IsArray($aSndID) Or Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID

	;prepare mci to receive time in milliseconds
	__SoundMciSendString("set " & $aSndID[0] & " time format miliseconds")
	;modify the $iHour, $iMin and $iSec parameters to be in milliseconds
	;and add to $iMs
	Local $iMs = $iSec * 1000
	$iMs += $iMin * 60 * 1000
	$iMs += $iHour * 60 * 60 * 1000
	If $aSndID[1] <> 0 Then
		$aSndID[2] = Round($iMs * $aSndID[1]) - $iMs
		$iMs = Round($iMs * $aSndID[1])
	EndIf
	; seek sound to time ($iMs)
	__SoundMciSendString("seek " & $aSndID[0] & " to " & $iMs)
	Local $iError = @error
	If _SoundPos($aSndID, 2) < 0 Then $aSndID[2] = 0
	;return
	If $iError Then Return SetError(1, $iError, 0)
	Return 1
EndFunc   ;==>_SoundSeek

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundStatus
; Description ...: All devices can return the "not ready", "paused", "playing", and "stopped" values.
; Syntax.........: _SoundStatus($aSndID)
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file
; Return values..: Success      - Sound status
;                  Failure      - 0 and set @error
;                  @error     3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......: Some devices can return the additional "open", "parked", "recording", and "seeking" values.(MSDN)
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundStatus($aSndID)
	If Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;return status
	Return __SoundMciSendString("status " & $aSndID[0] & " mode", 255)
EndFunc   ;==>_SoundStatus

; #FUNCTION# ====================================================================================================================
; Name...........: _SoundPos
; Description ...: Returns the current position of the song
; Syntax.........: _SoundPos($aSndID[, $iMode = 1])
; Parameters ....: $aSndID - Sound ID returned by _SoundOpen() or sound file,
;				   $iMode = 1 - hh:mm:ss, $iMode = 2 - milliseconds
; Return values..: Success      - Current position
;                  Failure      - 0 and set @error
;                  @error     1 - Invalid $iMode
;                  |3 - Invalid Sound ID or file name
; Author ........: RazerM, Melba23
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _SoundPos($aSndID, $iMode = 1)
	;validate $iMode
	If $iMode <> 1 And $iMode <> 2 Then Return SetError(1, 0, 0)
	If Not __SoundChkSndID($aSndID) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;tell mci to use time in milliseconds
	__SoundMciSendString("set " & $aSndID[0] & " time format miliseconds")
	;receive position of sound
	Local $iSndPosMs = Number(__SoundMciSendString("status " & $aSndID[0] & " position", 255))
	If $aSndID[1] <> 0 Then
		$iSndPosMs -= $aSndID[2]
	EndIf

	If $iMode = 2 Then Return $iSndPosMs

	;$iMode = 1 (hh:mm:ss)

	;modify data and assign to variables
	Local $iSndPosMin, $iSndPosHour, $iSndPosSecs
	__SoundTicksToTime($iSndPosMs, $iSndPosHour, $iSndPosMin, $iSndPosSecs)

	;assign formatted data to $sSndPosFormat
	Local $sSndPosHMS = StringFormat("%02i:%02i:%02i", $iSndPosHour, $iSndPosMin, $iSndPosSecs)

	;return correct variable
	Return $sSndPosHMS
EndFunc   ;==>_SoundPos

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __SoundChkSndID
; Description ...: Used internally within this file, not for general use
; Syntax.........: __SoundChkSndID(ByRef $aSndID, $bInit=False, $iPos=Default)
; Author ........: jpm
; Modified.......: Melba23
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __SoundChkSndID(ByRef $aSndID)
	If Not IsArray($aSndID) Then
		If Not FileExists($aSndID) Then Return 0 ; invalid Sound file
		Local $vTemp = FileGetShortName($aSndID)
		Dim $aSndID[4] = [$vTemp, 0, 0, $__SOUNDCONSTANT_SNDID_MARKER] ; create valid Sound ID array for use in UDF
	Else
		If UBound($aSndID) <> 4 And $aSndID[3] <> $__SOUNDCONSTANT_SNDID_MARKER Then Return 0 ; invalid Sound ID
	EndIf

	Return 1
EndFunc   ;==>__SoundChkSndID

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __SoundMciSendString
; Description ...: Used internally within this file, not for general use
; Syntax.........: __SoundMciSendString($string[, $iLen = 0])
; Author ........: RazerM, Melba23
; Modified.......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __SoundMciSendString($string, $iLen = 0)
	Local $iRet = DllCall("winmm.dll", "dword", "mciSendStringW", "wstr", $string, "wstr", "", "uint", $iLen, "ptr", 0)
	If @error Then Return SetError(@error, @extended, "")
	If $iRet[0] Then Return SetError(10, $iRet[0], $iRet[2])
	Return $iRet[2]
EndFunc   ;==>__SoundMciSendString

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __SoundReadTLENFromMP3
; Description ...: Used internally within this file, not for general use
; Syntax.........: __SoundReadTLENFromMP3($sTag)
; Parameters ....: $sTag - >= 1024 bytes from 'read raw' mode.
; Return values .: Success      - Sound length (hh:mm:ss)
;                  Failure      - 0 and @error = 1
; Author ........: Melba23
; Modified.......: RazerM
; Remarks .......: File must be an mp3 AFAIK
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __SoundReadTLENFromMP3($sTag)
	; Check that an ID3v2.3 tag is present
	If StringLeft($sTag, 10) <> "0x49443303" Then Return SetError(1, 0, 0) ; ID3

	Local $iTemp = StringInStr($sTag, "544C454E") + 21 ; TLEN
	$sTag = StringTrimLeft($sTag, $iTemp)
	Local $sTemp = ""

	For $i = 1 To 32 Step 2
		If StringMid($sTag, $i, 2) = "00" Then
			ExitLoop
		Else
			$sTemp &= StringMid($sTag, $i, 2)
		EndIf
	Next

	Local $iLengthMs = Number(BinaryToString("0x" & $sTemp)) ; Number( HexToString($sTemp) )

	If $iLengthMs <= 0 Then Return SetError(1, 0, 0)
	Local $iLengthHour, $iLengthMin, $iLengthSecs
	__SoundTicksToTime($iLengthMs, $iLengthHour, $iLengthMin, $iLengthSecs)

	;Convert to hh:mm:ss and return
	Return StringFormat("%02i:%02i:%02i", $iLengthHour, $iLengthMin, $iLengthSecs)
EndFunc   ;==>__SoundReadTLENFromMP3

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __SoundReadXingFromMP3
; Syntax.........: __SoundReadXingFromMP3($sTag)
; Parameters ....: $sTag - first 5156 bytes from 'read raw' mode.
; Return values .: Success      - Sound length (hh:mm:ss)
;                  Failure      - 0 and @error = 1
; Author ........: Melba23
; Modified.......: RazerM
; Remarks .......: File must be an mp3 AFAIK
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __SoundReadXingFromMP3($sTag)
	Local $iXingPos = StringInStr($sTag, "58696E67") ; Xing
	If $iXingPos = 0 Then Return SetError(1, 0, 0)

	; Read fields flag
	Local $iFrames, $iFlags = Number("0x" & StringMid($sTag, $iXingPos + 14, 2))
	If BitAND($iFlags, 1) = 1 Then
		$iFrames = Number("0x" & StringMid($sTag, $iXingPos + 16, 8))
	Else
		Return SetError(1, 0, 0); No frames field
	EndIf

	; Now to find Samples per frame & Sampling rate
	; Go back to the frame header start
	Local $sHeader = StringMid($sTag, $iXingPos - 72, 8)

	; Read the relevant bytes
	Local $iMPEGByte = Number("0x" & StringMid($sHeader, 4, 1))
	Local $iFreqByte = Number("0x" & StringMid($sHeader, 6, 1))

	; Decode them
	; 8 = MPEG-1, 0 = MPEG-2
	Local $iMPEGVer = BitAND($iMPEGByte, 8)

	; 2 = Layer III, 4 = Layer II, 6 = Layer I
	Local $iLayerNum = BitAND($iMPEGByte, 6)

	Local $iSamples
	Switch $iLayerNum
		Case 6
			$iSamples = 384
		Case 4
			$iSamples = 1152
		Case 2
			Switch $iMPEGVer
				Case 8
					$iSamples = 1152
				Case 0
					$iSamples = 576
				Case Else
					$iSamples = 0
			EndSwitch
		Case Else
			$iSamples = 0
	EndSwitch

	; If not valid return
	If $iSamples = 0 Then Return SetError(1, 0, 0)

	; 0 = bit 00, 4 = Bit 01, 8 = Bit 10
	Local $iFrequency, $iFreqNum = BitAND($iFreqByte, 12)
	Switch $iFreqNum
		Case 0
			$iFrequency = 44100
		Case 4
			$iFrequency = 48000
		Case 8
			$iFrequency = 32000
		Case Else
			$iFrequency = 0
	EndSwitch

	; If not valid return
	If $iFrequency = 0 Then Return SetError(1, 0, 0)

	; MPEG-2 halves the value
	If $iMPEGVer = 0 Then $iFrequency = $iFrequency / 2

	; Duration in secs = No of frames * Samples per frame / Sampling freq
	Local $iLengthMs = Int(($iFrames * $iSamples / $iFrequency) * 1000)

	; Convert to hh:mm:ss and return
	Local $iLengthHours, $iLengthMins, $iLengthSecs
	__SoundTicksToTime($iLengthMs, $iLengthHours, $iLengthMins, $iLengthSecs)

	Return StringFormat("%02i:%02i:%02i", $iLengthHours, $iLengthMins, $iLengthSecs)
EndFunc   ;==>__SoundReadXingFromMP3

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _TicksToTime
; Description ...: Converts the specified tick amount to hours, minutes and seconds.
; Syntax.........: _TicksToTime($iTicks, ByRef $iHours, ByRef $iMins, ByRef $iSecs)
; Parameters ....: $iTicks - Tick amount.
;                  $iHours - Variable to store the hours.
;                  $iMins - Variable to store the minutes.
;                  $iSecs - Variable to store the seconds.
; Return values .: Success - 1
;                  Failure - 0
;                  @Error - 0 - No error.
;                  |1 - $iTicks isn't an integer.
; Author ........: Marc <mrd at gmx de>
; Modified.......:
; Remarks .......:
; Related .......: __SoundTimeToTicks
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func __SoundTicksToTime($iTicks, ByRef $iHours, ByRef $iMins, ByRef $iSecs)
	If Number($iTicks) < 0 Then Return SetError(1, 0, 0)
	If Number($iTicks) = 0 Then
		$iHours = 0
		$iTicks = 0
		$iMins = 0
		$iSecs = 0
		Return 1
	EndIf
	$iTicks = Round($iTicks / 1000)
	$iHours = Int($iTicks / 3600)
	$iTicks = Mod($iTicks, 3600)
	$iMins = Int($iTicks / 60)
	$iSecs = Round(Mod($iTicks, 60))
	; If $iHours = 0 then $iHours = 24
	Return 1
EndFunc   ;==>__SoundTicksToTime

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _TimeToTicks
; Description ...: Converts the specified hours, minutes, and seconds to ticks.
; Syntax.........: _TimeToTicks([$iHours = @HOUR[, $iMins = @MIN[, $iSecs = @SEC]]])
; Parameters ....: $iHours - The hours.
;                  $iMins - The minutes.
;                  $iSecs - The seconds.
; Return values .: Success - Returns the number of ticks.
;                  Failure - 0
;                  @Error - 0 - No error.
;                  |1 - The specified hours, minutes, or seconds are not valid.
; Author ........: Marc <mrd at gmx de>
; Modified.......: SlimShady: added the default time and made parameters optional
; Remarks .......:
; Related .......: _TicksToTime
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func __SoundTimeToTicks($iHours = @HOUR, $iMins = @MIN, $iSecs = @SEC)
	If Not (StringIsInt($iHours) And StringIsInt($iMins) And StringIsInt($iSecs)) Then Return SetError(1, 0, 0)
	Return 1000 * ((3600 * $iHours) + (60 * $iMins) + $iSecs)
EndFunc   ;==>__SoundTimeToTicks

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _Off
; Description ...: Desactiva el audio
; Syntax.........: _SoundOff(ByRef $aSndID)
; Parameters ....: $aSndID - Identificador de un sonido (ID del sonido).
; Return values .: Si falla errores
; Author ........: Bethory
; Modified.......:
; Remarks .......:
; Related .......: 
; Link ..........:
; Example .......: Aun no
; ===============================================================================================================================
Func _SoundOff(ByRef $aSndID)
	Local $vTemp = $aSndID
	If Not __SoundChkSndID($vTemp) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;reset VBR factor if used
	If IsArray($aSndID) Then $aSndID[2] = 0
	__SoundMciSendString("setaudio " & $vTemp[0] & " off") ;desactiva el audio
	If @error Then Return SetError(2, @error, 0)
EndFunc   ;==>_SoundOff

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _LeftBalance
; Description ...: asigna un valor de balance al canal izquierdo
; Syntax.........: _LeftBalance(ByRef $aSndID, ByRef $volumenIzq)
; Parameters ....: $aSndID - Identificador de un sonido (ID del sonido).
;                  $volumenIzq - Rango de Volumen para el canal izquierdo 0 hasta 1000
; Return values .: Errores
; Author ........: Bethory
; Modified.......:
; Remarks .......:
; Related .......: __SoundRightBalance
; Link ..........:
; Example .......: Aun no
; ===============================================================================================================================
Func _SoundLeftBalance(ByRef $aSndID, $volumenIzq)
	Local $vTemp = $aSndID
	If Not __SoundChkSndID($vTemp) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;reset VBR factor if used
	If IsArray($aSndID) Then $aSndID[2] = 0
	__SoundMciSendString("setaudio " & $vTemp[0] & " left volume to " & $volumenIzq)
	If @error Then Return SetError(2, @error, 0)
EndFunc   ;==>_SoundLeftBalance

; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: _RightBalance
; Description ...: asigna un valor de balance al canal izquierdo
; Syntax.........: _LeftBalance(ByRef $aSndID, ByRef $volumenDer)
; Parameters ....: $aSndID - Identificador de un sonido (ID del sonido).
;                  $volumenIzq - Rango de Volumen para el canal izquierdo 0 hasta 1000
; Return values .: Errores
; Author ........: Bethory
; Modified.......:
; Remarks .......:
; Related .......: __SoundRightBalance
; Link ..........:
; Example .......: Aun no
; ===============================================================================================================================
Func _SoundRightBalance(ByRef $aSndID, $volumenDer)
	Local $vTemp = $aSndID
	If Not __SoundChkSndID($vTemp) Then Return SetError(3, 0, 0) ; invalid Sound ID or file name

	;reset VBR factor if used
	If IsArray($aSndID) Then $aSndID[2] = 0
	__SoundMciSendString("setaudio " & $vTemp[0] & " right volume to " & $volumenDer)
	If @error Then Return SetError(2, @error, 0)
EndFunc   ;==>_SoundRightBalance
no siendo más ... me despido de nuevo muchas gracias :smt002
Me gustaría arreglar el mundo.... pero no me han dado el código fuente xD
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Reproducción de audio por un canal

Mensaje por Ximorro »

Muy bien el programita, interesante ejemplo de uso de las posibilidades de winmm.dll.

Una cosa, creo que no es muy correcto modificar una librería públicamente distribuida de esta manera.
Esa librería tiene unos autores que la han hecho y la mantienen, si cada uno se pone a modificarla a su antojo habrá por la red cientos de versiones que harán un montón de cosas diferentes.
Veo dos opciones, la más directa es simplemente poner esas funciones en tu programa, es una funcionalidad que has añadido tú apoyándote en la librería, pero no pertenece a ella.
La otra opción es que si te parece que esas funciones deberían formar parte de sound.au3, te pongas en contacto con los autores de la librería original y les muestres tu trabajo. Si les gusta seguro que las incluirán oficialmente y pondrán tu nombre en la lista de creadores o colaboradores. ¡Adelante!
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Responder