RazerM Posted October 6, 2008 Author Share Posted October 6, 2008 Thanks, that should have been there from the start My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop. Link to comment Share on other sites More sharing options...
RazerM Posted October 7, 2008 Author Share Posted October 7, 2008 New beta:expandcollapse popup#include <Date.au3> #include <File.au3> #include <String.au3> ;=============================================================================== ; ; Function Name: _SoundOpen ; Description:: Opens a sound file for use with other _Sound functions ; Parameter(s): $sFile - The sound file, $sAlias[optional] - a name such as sound1, ; if you do not specify one it is randomly generated ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): string(the sound id) - Success, 0 - Failure ; @extended <> 0 - open failed, @error = 2 - File doesn't exist, ; @error = 3 - alias contains whitespace ; Author(s): RazerM, Melba23, some code by Simucal, PsaltyDS ; ;=============================================================================== ; Func _SoundOpen($sFile, $sAlias = "") ;Declare variables Local $aSndID[3], $sSndID, $iCurrentPos, $iRet, $asAlias, $fTryNextMethod = False Local $szDrive, $szDir, $szFName, $szExt, $iSndLenMs, $iSndLenMin, $iSndLenHour, $iSndLenSecs, $sSndLenFormat Local $sSndDirName, $sSndFileName, $sSndDirShortName, $oShell, $oShellDir, $oShellDirFile, $sRaw, $aInfo Local $sTrackLength, $iSoundTicks, $iActualTicks, $iVBRRatio, $aiTime ;check for file If Not FileExists($sFile) Then Return SetError(2, 0, 0) ;search for whitespace by character $asAlias = StringSplit($sAlias, "") For $iCurrentPos = 1 To $asAlias[0] If StringIsSpace($asAlias[$iCurrentPos]) Then Return SetError(3, 0, 0) Next ;create random alias if one is not supplied If $sAlias = "" Then $sSndID = __RandomStr(10) Else $sSndID = $sAlias EndIf If StringInStr($sSndID, '!') Then Return SetError(3, 0, 0) ;invalid file/alias $aSndID[0] = $sSndID _PathSplit($sFile, $szDrive, $szDir, $szFName, $szExt) If $szDrive = "" Then $sSndDirName = @WorkingDir & "\" Else $sSndDirName = $szDrive & $szDir EndIf $sSndFileName = $szFName & $szExt $sSndDirShortName = FileGetShortName($sSndDirName, 1) ;open file $iRet = __mciSendString("open " & FileGetShortName($sFile) & " alias " & $aSndID[0]) If $szExt = ".mp3" Then $sTrackLength = __ReadXingFromMP3(FileGetShortName($sSndDirName & $sSndFileName)) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf If $fTryNextMethod And $szExt = ".mp3" Then $sTrackLength = __ReadTLENFromMP3(FileGetShortName($sSndDirName & $sSndFileName)) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf If $fTryNextMethod Then $fTryNextMethod = False $oShell = ObjCreate("shell.application") If IsObj($oShell) Then $oShellDir = $oShell.NameSpace ($sSndDirShortName) If IsObj($oShellDir) Then $oShellDirFile = $oShellDir.Parsename ($sSndFileName) If IsObj($oShellDirFile) Then $sRaw = $oShellDir.GetDetailsOf ($oShellDirFile, -1) $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 EndIf If $fTryNextMethod Then ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;receive length of sound $iSndLenMs = __mciSendString("status " & $aSndID[0] & " length", 255) ;assign modified data to variables _TicksToTime($iSndLenMs, $iSndLenHour, $iSndLenMin, $iSndLenSecs) ;assign formatted data to $sSndLenFormat $sTrackLength = StringFormat("%02i:%02i:%02i", $iSndLenHour, $iSndLenMin, $iSndLenSecs) $fTryNextMethod = False EndIf ; Convert Track_Length to mSec $aiTime = StringSplit($sTrackLength, ":") $iActualTicks = _TimeToTicks($aiTime[1], $aiTime[2], $aiTime[3]) ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;;Get estimated length $iSoundTicks = __mciSendString("status " & $aSndID[0] & " length", 255) ;Compare to actual length 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 Return SetError(0, $iRet, $aSndID) EndFunc ;==>_SoundOpen ;=============================================================================== ; ; Function Name: _SoundClose ; Description:: Closes a sound ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundClose($aSndID) If Not IsArray($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias If __mciSendString("close " & $aSndID[0]) = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundClose ;=============================================================================== ; ; Function Name: _SoundPlay ; Description:: Plays a sound from the current position (beginning is the default) ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; $fWait - If set to 1 the script will wait for the sound to finish before continuing ; - If set to 0 the script will continue while the sound is playing ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 - Failure ; @error = 2 - $fWait is invalid, @error = 1 - play failed ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundPlay($aSndID, $fWait = 0) ;Declare variables Local $iRet, $vTemp ;validate $fWait If $fWait <> 0 And $fWait <> 1 Then Return SetError(2, 0, 0) If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;if sound has finished, seek to start If _SoundPos($aSndID, 2) = _SoundLength($aSndID, 2) Then __mciSendString("seek " & $aSndID[0] & " to start") ;If $fWait = 1 then pass wait to mci If $fWait = 1 Then $iRet = __mciSendString("play " & $aSndID[0] & " wait") Else $iRet = __mciSendString("play " & $aSndID[0]) EndIf ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundPlay ;=============================================================================== ; ; Function Name: _SoundStop ; Description:: Stops the sound ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundStop($aSndID) ;Declare variables Local $iRet, $iRet2, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;seek to start $iRet = __mciSendString("seek " & $aSndID[0] & " to start") ;stop $iRet2 = __mciSendString("stop " & $aSndID[0]) ;return If $iRet = 0 And $iRet2 = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundStop ;=============================================================================== ; ; Function Name: _SoundPause ; Description:: Pauses the sound ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundPause($aSndID) ;Declare variables Local $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;pause sound $iRet = __mciSendString("pause " & $aSndID[0]) ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundPause ;=============================================================================== ; ; Function Name: _SoundResume ; Description:: Resumes the sound after being paused ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundResume($aSndID) ;Declare variables Local $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;resume sound $iRet = __mciSendString("resume " & $aSndID[0]) ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundResume ;=============================================================================== ; ; Function Name: _SoundLength ; Description:: Returns the length of the sound in the format hh:mm:ss ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file, ; $iMode = 1 - hh:mm:ss, $iMode = 2 - milliseconds ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): Length of the sound - Success, 0 and @error = 1 - $iMode is invalid ; Author(s): RazerM, Melba23 ; Mofified: jpm ; ;=============================================================================== ; Func _SoundLength($aSndID, $iMode = 1) ;Declare variables Local $iSndLenMs, $iSndLenMin, $iSndLenHour, $iSndLenSecs, $sSndLenFormat, $vTemp = "" ;validate $iMode If $iMode <> 1 And $iMode <> 2 Then Return SetError(1, 0, 0) If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[3] $aSndID = _SoundOpen($vTemp) EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;receive length of sound $iSndLenMs = __mciSendString("status " & $aSndID[0] & " length", 255) If $aSndID[1] <> 0 Then $iSndLenMs = Round($iSndLenMs / $aSndID[1]) If $vTemp <> "" Then _SoundClose($aSndID) ;if user called _SoundLength with a filename ;assign modified data to variables _TicksToTime($iSndLenMs, $iSndLenHour, $iSndLenMin, $iSndLenSecs) ;assign formatted data to $sSndLenFormat $sSndLenFormat = StringFormat("%02i:%02i:%02i", $iSndLenHour, $iSndLenMin, $iSndLenSecs) ;return correct variable If $iMode = 1 Then Return $sSndLenFormat If $iMode = 2 Then Return $iSndLenMs EndFunc ;==>_SoundLength ;=============================================================================== ; ; Function Name: _SoundSeek ; Description:: Seeks the sound to a specified time ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen (must NOT be a file), $iHour, $iMin, $iSec ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundSeek(ByRef $aSndID, $iHour, $iMin, $iSec) ;Declare variables Local $iMs = 0, $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;prepare mci to receive time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;modify the $iHour, $iMin and $iSec parameters to be in milliseconds ;and add to $iMs $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) $iRet = __mciSendString("seek " & $aSndID[0] & " to " & $iMs) If _SoundPos($aSndID, 2) < 0 Then $aSndID[2] = 0 ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundSeek ;=============================================================================== ; ; Function Name: _SoundStatus ; Description:: All devices can return the "not ready", "paused", "playing", and "stopped" values. ; Some devices can return the additional "open", "parked", "recording", and "seeking" values.(MSDN) ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): Sound Status ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundStatus($aSndID) Local $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;return status Return __mciSendString("status " & $aSndID[0] & " mode", 255) EndFunc ;==>_SoundStatus ;=============================================================================== ; ; Function Name: _SoundPos ; Description:: Returns the current position of the song ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file, ; $iMode = 1 - hh:mm:ss, $iMode = 2 - milliseconds ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): Current Position - Success, @error = 1 - $iMode is invalid ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundPos($aSndID, $iMode = 1) ;Declare variables Local $iSndPosMs, $iSndPosMin, $iSndPosHour, $iSndPosSecs, $sSndPosFormat, $vTemp ;validate $iMode If $iMode <> 1 And $iMode <> 2 Then Return SetError(1, 0, 0) If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;receive position of sound $iSndPosMs = __mciSendString("status " & $aSndID[0] & " position", 255) If $aSndID[1] <> 0 Then $iSndPosMs -= $aSndID[2] EndIf ;modify data and assign to variables _TicksToTime($iSndPosMs, $iSndPosHour, $iSndPosMin, $iSndPosSecs) ;assign formatted data to $sSndPosFormat $sSndPosFormat = StringFormat("%02i:%02i:%02i", $iSndPosHour, $iSndPosMin, $iSndPosSecs) ;return correct variable If $iMode = 1 Then Return $sSndPosFormat If $iMode = 2 Then Return $iSndPosMs EndFunc ;==>_SoundPos ;internal functions Func __mciSendString($string, $iLen = 0) Local $iRet $iRet = DllCall("winmm.dll", "int", "mciSendStringA", "str", $string, "str", "", "long", $iLen, "long", 0) If Not @error Then Return $iRet[2] EndFunc ;==>__mciSendString Func __RandomStr($LEN) Local $string For $iCurrentPos = 1 To $LEN $string &= Chr(Random(97, 122, 1)) Next Return $string EndFunc ;==>__RandomStr ;=============================================================================== ; ; Function Name: [private] __ReadTLENFromMP3 ; Description:: Used internally within this file, not for general use ; Parameter(s): $sFile - filename of mp3 ; Requirement(s): File must be an mp3 AFAIK ; Return Value(s): Sound length (hh:mm:ss) - Success, 0 and @error = 1 - Failure ; Author(s): Melba23 ; Modified: RazerM ; ;=============================================================================== ; Func __ReadTLENFromMP3($sFile) Local $hFile, $sTag, $iLengthMs, $iLengthHour, $iLengthMin, $iLengthSecs ; Read tag info from file $hFile = FileOpen($sFile, 4) $sTag = FileRead($hFile, 1024) FileClose($hFile) ; Check that an ID3v2.3 tag is present If StringLeft($sTag, 10) <> "0x49443303" Then Return SetError(1, 0, 0) $iLengthMs = Number(_HexToString(StringTrimLeft($sTag, StringInStr($sTag, "544C454E") + 21))) If $iLengthMs > 0 Then _TicksToTime($iLengthMs, $iLengthHour, $iLengthMin, $iLengthSecs) ;Convert to hh:mm:ss and return Return StringFormat("%02i:%02i:%02i", $iLengthHour, $iLengthMin, $iLengthSecs) Else Return SetError(1, 0, 0) EndIf EndFunc ;==>__ReadTLENFromMP3 ;=============================================================================== ; ; Function Name: [private] __ReadXingFromMP3 ; Description:: Used internally within this file, not for general use ; Parameter(s): $sFile - filename of mp3 ; Requirement(s): File must be an mp3 AFAIK ; Return Value(s): Sound length (hh:mm:ss) - Success, 0 and @error = 1 - Failure ; Author(s): Melba23 ; Modified: RazerM ; ;=============================================================================== ; Func __ReadXingFromMP3($sFile) Local $hFile, $sTag, $iXingPos, $iFlags, $iFrames, $sHeader, $iMPEGByte, $iFreqByte, $iMPEGVer, $iLayerNum, $iSamples, $iFreqNum, $iFrequency, $iLengthMs, $iLengthHours, $iLengthMins, $iLengthSecs ; Read tag info from file $hFile = FileOpen($sFile, 4) $sTag = FileRead($hFile, 5156) FileClose($hFile) $iXingPos = StringInStr($sTag, "58696E67") If $iXingPos = 0 Then Return SetError(1, 0, 0) ; Read fields flag $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 $sHeader = StringMid($sTag, $iXingPos - 72, 8) ; Read the relevant bytes $iMPEGByte = Number("0x" & StringMid($sHeader, 4, 1)) $iFreqByte = Number("0x" & StringMid($sHeader, 6, 1)) ; Decode them ; 8 = MPEG-1, 0 = MPEG-2 $iMPEGVer = BitAND($iMPEGByte, 8) ; 2 = Layer III, 4 = Layer II, 6 = Layer I $iLayerNum = BitAND($iMPEGByte, 6) 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 $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 $iLengthMs = Int(($iFrames * $iSamples / $iFrequency) * 1000) ; Convert to hh:mm:ss and return _TicksToTime($iLengthMs, $iLengthHours, $iLengthMins, $iLengthSecs) Return StringFormat("%02i:%02i:%02i", $iLengthHours, $iLengthMins, $iLengthSecs) EndFunc ;==>__ReadXingFromMP3Changes:_SoundPos() reporting incorrect value for long audio files._SoundLength() reports correct length with filenames now.Added Xing and TLEN methods for mp3 files.Internal functions use double underscores now.Changed variable names to improve readability.Now uses _TicksToTime() and _TimeToTicks(). My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 9, 2008 Moderators Share Posted October 9, 2008 RazerM, A couple of small problems with the beta. 1. The following section of _SoundOpen does not do what you believe it does:If $fTryNextMethod And $szExt = ".mp3" Then $sTrackLength = __ReadTLENFromMP3(FileGetShortName($sSndDirName & $sSndFileName)) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf Even if an mp3 file has read the Xing header successfully, it will pass through the "Else" section and reset $fTryNextMethod. So it will try to read from the properties. If the properties method does not work correctly (on an older version of Windows), and it is a VBR file, you get the incorrect MCI length returned. If you change the section slightly, it resolves the problem:If $fTryNextMethod Then If $szExt = ".mp3" Then $sTrackLength = __ReadTLENFromMP3(FileGetShortName($sSndDirName & $sSndFileName)) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf EndIf And now the whole section is skipped if the Xing header method found a value. 2. I have discovered a small bug (or feature!) in the ANSI version of AutoIt. I used _HexToString when finding the TLEN length. In my VISTA machine, _HexToString truncates the hex bytes when it meets anything below 0x20. So as the length bytes are terminated by a string of 0x00s it worked without problem. On the ANSI version of AutoIt, _HexToString keeps going, so the string was as long as the tag it was read from and the Number function went "Tilt". I realise this only affects ANSI AutoIT, support for which Jon is about to remove, but as some users might still want to use the Sound UDF, I have come up with the following which works on both versions:;Instead of this: $iLengthMs = Number(_HexToString(StringTrimLeft($sTag, StringInStr($sTag, "544C454E") + 21))) ; Use this: $iTemp = StringInStr($sTag, "544C454E") + 21 $sTag = StringTrimLeft($sTag, $iTemp) $sTemp = "" For $i = 1 To 32 Step 2 If StringMid($sTag, $i, 2) = "00" Then ExitLoop Else $sTemp &= StringMid($sTag, $i, 2) EndIf Next $iLengthMs = Number($sTemp) As written it requires 2 new local variables ($iTemp and $sTemp), so feel free to play with it if you can make it tauter. Other than these 2 points, the beta works well. And if it had not been for the first, I would never have discovered the second - it was because I got a strange length from a file that I knew had both Xing and TLEN that I started investigating. A couple of suggestions, if I may: - Why not read the file once only and then look for Xing and TLEN? At present both these internal functions read the file and CBR files without a Xing header will always have to read twice. - As future versions of AutoIt will apparently only support later versions of Windows which include the file properties method, why not look to that first and possibly avoid any file reading? Thanks for the effort, M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
RazerM Posted October 9, 2008 Author Share Posted October 9, 2008 RazerM, A couple of small problems with the beta. 1. The following section of _SoundOpen does not do what you believe it does:If $fTryNextMethod And $szExt = ".mp3" Then $sTrackLength = __ReadTLENFromMP3(FileGetShortName($sSndDirName & $sSndFileName)) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf Even if an mp3 file has read the Xing header successfully, it will pass through the "Else" section and reset $fTryNextMethod. So it will try to read from the properties. If the properties method does not work correctly (on an older version of Windows), and it is a VBR file, you get the incorrect MCI length returned. If you change the section slightly, it resolves the problem:If $fTryNextMethod Then If $szExt = ".mp3" Then $sTrackLength = __ReadTLENFromMP3(FileGetShortName($sSndDirName & $sSndFileName)) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf EndIf And now the whole section is skipped if the Xing header method found a value.Thanks, I never thought that through. Will be fixed soon. 2. I have discovered a small bug (or feature!) in the ANSI version of AutoIt. I used _HexToString when finding the TLEN length. In my VISTA machine, _HexToString truncates the hex bytes when it meets anything below 0x20. So as the length bytes are terminated by a string of 0x00s it worked without problem. On the ANSI version of AutoIt, _HexToString keeps going, so the string was as long as the tag it was read from and the Number function went "Tilt". I realise this only affects ANSI AutoIT, support for which Jon is about to remove, but as some users might still want to use the Sound UDF, I have come up with the following which works on both versions:;Instead of this: $iLengthMs = Number(_HexToString(StringTrimLeft($sTag, StringInStr($sTag, "544C454E") + 21))) ; Use this: $iTemp = StringInStr($sTag, "544C454E") + 21 $sTag = StringTrimLeft($sTag, $iTemp) $sTemp = "" For $i = 1 To 32 Step 2 If StringMid($sTag, $i, 2) = "00" Then ExitLoop Else $sTemp &= StringMid($sTag, $i, 2) EndIf Next $iLengthMs = Number($sTemp) As written it requires 2 new local variables ($iTemp and $sTemp), so feel free to play with it if you can make it tauter. Other than these 2 points, the beta works well. And if it had not been for the first, I would never have discovered the second - it was because I got a strange length from a file that I knew had both Xing and TLEN that I started investigating.This will also be fixed. I don't entirely understand what is happening here , so thanks for the help. A couple of suggestions, if I may: - Why not read the file once only and then look for Xing and TLEN? At present both these internal functions read the file and CBR files without a Xing header will always have to read twice. - As future versions of AutoIt will apparently only support later versions of Windows which include the file properties method, why not look to that first and possibly avoid any file reading? Thanks for the effort, M231. Yes that makes more sense, I shall change it to pass the file handle into the helper functions. 2. I did this because Xing and TLEN are set especially to cater for this purpose, but it does make more sense with file properties first now that you mention the hit it would have on CBR files. My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 10, 2008 Moderators Share Posted October 10, 2008 (edited) RazerM,My apologies for not explaining the TLEN and Xing code better.1. Xing: The encoder should put an MP3 frame in a VBR file containing the data needed to work out the length of the file. This frame has the following internal structure:An MP3 header (always 0xFFF, followed by the various bytes as explained in one of my earlier posts)36 bytes later you find the string "Xing". CBR files either have a similar header containing the string "Info" or nothing. Easiest way to find the string is to search directly.; Read tag info from file $file_handle = FileOpen($Passed_File_Name, 4) $Tag = FileRead($file_handle, 5156) FileClose($file_handle) $Xing_Pos = StringInStr($Tag, "58696E67")Immediately after the "Xing" is a DWord indicating the information to follow. If the 1 bit is set here, the number of frames is present (and I have not yet found a Xing header which does not have this field, because without it there is no point in having the header!). If the field is present, read the DWord to get the frame count.; Read fields flag $Flags = Number("0x" & StringMid($Tag, $Xing_Pos + 14, 2)) If BitAND($Flags, 1) = 1 Then $Frames = Number("0x" & StringMid($Tag, $Xing_Pos + 16, 8)) Else Return 0; No frames field EndIfTo calculate the length, we use: Length = No of frames * Samples per frame / Sampling freq. The other factors are in the mp3 frame header, so return 36 bytes from the "Xing" string to the frame header itself, read the relevant bytes and calculate the factors.; Go back to the frame header start $Mp3_Header = StringMid($Tag, $Xing_Pos - 72, 8) ; Read the relevant bytes $MPEG_byte = Number("0x" & StringMid($Mp3_Header, 4, 1)) $Freq_byte = Number("0x" & StringMid($Mp3_Header, 6, 1)) ; Decode the bytes using a couple of Switch blocksAnd so calculate the length of the file.2. TLEN: An ID3v2.3 header is the only version normally placed before the file itself (other versions add to the end so the whole file does not have to be rewritten when tagging). It contains various fields, all denoted by a 4-letter code. The main ones are:TALB - Album nameTIT2 - Title (there are also TIT1 and TIT3 out of interest!)TPE1 - Performer or ArtistTRCK - Track numberTCON - GenreMCDI - CD ID code and of course TLEN - length in ms.The ID3v2 header always starts "ID3" followed by the version number (because we need v2.3), so we look for that string:; Read tag info from file $file_handle = FileOpen($Passed_File_Name, 4) $Tag = FileRead($file_handle, 1024) FileClose($file_handle) ; Check that an ID3v2.3 tag is present If StringLeft($Tag, 10) <> "0x49443303" Then Return -1If there is a tag, look for the "TLEN" string within it. Like all tag fields, TLEN has the following structure:4 bytes - field title (i.e. TLEN)4 bytes(DWord) - length of the the field (ie offset to next field)3 bytes - all 0Field dataso we need to trim the tag to the beginning of the field data:$temp = StringInStr($Tag, "544C454E") $Tag = StringTrimLeft($Tag, $temp + 21)It would be helpful if we could use the field length byte, but some of the fields, and TLEN in particular, have a field length much longer than the actual data (no idea why). Fortunately in the TLEN case, the field is completed by 0x00 bytes, so we have only to read the ASCII numeric bytes and stop at the first 00 byte. This is where the small bug in _HexToString appeared. In Vista it stops automatically when it tries to encode a 0x00 byte - in Win98 it keeps going! So we need a little loop to look for the first 0x00 byte (I thought of just searching for "00" but then realised that the final ASCII byte might be 30). And of course, there are often TLEN fields with no content, just 0x00 bytes (again no idea why):$temp = "" For $i = 1 To 32 Step 2 If StringMid($Tag, $i, 2) = "00" Then ExitLoop Else $temp &= StringMid($Tag, $i, 2) EndIf NextNow we have the ASCII bytes encoding the length, so convert them to string and then number:$TLEN = Number(_HexToString($temp))I hope that is a bit clearer. And if you now want to tighten up the code, please feel free.For even more detail, I recommend the following websites:http://www.id3.org/ for the ID3 tagshttp://www.codeproject.com/KB/audio-video/mpegaudioinfo.aspx for the mp3 headersRight, one last thing. Poking around the MSDN MCI site, I came across the following MCI volume control and wondered if you might consider including it in Sound.au3. I know AutoIt has its own volume control with SoundSetWaveVolume, but I found this function does not work in Win98 whereas the MCI one does. I have written the UDF in the current Sound UDF format so it can use the __mciSendString function:Func _SoundVolume($aSndID, $iVolume); $Volume: 0(mute) - 1000(full) ;Declare variables Local $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0); invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0); invalid file/alias $iVolume = Int($iVolume) If $iVolume < 0 Or $iVolume > 1000 Then Return SetError(2, 0, 0); invalid volume ;change volume $iRet = __mciSendString("setaudio " & $ aSndID[0] & " volume to "& $iVolume) ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc;==>_SoundVolumeI hope the forum holds together long enough to get this finished!M23 Edited October 10, 2008 by Melba23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
RazerM Posted October 10, 2008 Author Share Posted October 10, 2008 (edited) New beta:expandcollapse popup#include <Date.au3> #include <File.au3> #include <String.au3> ;=============================================================================== ; ; Function Name: _SoundOpen ; Description:: Opens a sound file for use with other _Sound functions ; Parameter(s): $sFile - The sound file, $sAlias[optional] - a name such as sound1, ; if you do not specify one it is randomly generated ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): string(the sound id) - Success, 0 - Failure ; @extended <> 0 - open failed, @error = 2 - File doesn't exist, ; @error = 3 - alias contains whitespace ; Author(s): RazerM, Melba23, some code by Simucal, PsaltyDS ; ;=============================================================================== ; Func _SoundOpen($sFile, $sAlias = "") ;Declare variables Local $aSndID[3], $sSndID, $iCurrentPos, $iRet, $asAlias, $fTryNextMethod = False, $hFile Local $szDrive, $szDir, $szFName, $szExt, $iSndLenMs, $iSndLenMin, $iSndLenHour, $iSndLenSecs, $sSndLenFormat Local $sSndDirName, $sSndFileName, $sSndDirShortName, $oShell, $oShellDir, $oShellDirFile, $sRaw, $aInfo Local $sTrackLength, $iSoundTicks, $iActualTicks, $iVBRRatio, $aiTime ;check for file If Not FileExists($sFile) Then Return SetError(2, 0, 0) ;search for whitespace by character $asAlias = StringSplit($sAlias, "") For $iCurrentPos = 1 To $asAlias[0] If StringIsSpace($asAlias[$iCurrentPos]) Then Return SetError(3, 0, 0) Next ;create random alias if one is not supplied If $sAlias = "" Then $sSndID = __RandomStr(10) Else $sSndID = $sAlias EndIf If StringInStr($sSndID, '!') Then Return SetError(3, 0, 0) ;invalid file/alias $aSndID[0] = $sSndID _PathSplit($sFile, $szDrive, $szDir, $szFName, $szExt) If $szDrive = "" Then $sSndDirName = @WorkingDir & "\" Else $sSndDirName = $szDrive & $szDir EndIf $sSndFileName = $szFName & $szExt $sSndDirShortName = FileGetShortName($sSndDirName, 1) ;open file $iRet = __mciSendString("open " & FileGetShortName($sFile) & " alias " & $aSndID[0]) $oShell = ObjCreate("shell.application") If IsObj($oShell) Then $oShellDir = $oShell.NameSpace ($sSndDirShortName) If IsObj($oShellDir) Then $oShellDirFile = $oShellDir.Parsename ($sSndFileName) If IsObj($oShellDirFile) Then $sRaw = $oShellDir.GetDetailsOf ($oShellDirFile, -1) $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 If $fTryNextMethod Then $fTryNextMethod = False If $szExt = ".mp3" Then $hFile = FileOpen(FileGetShortName($sSndDirName & $sSndFileName), 4) $sTag = FileRead($hFile, 5156) FileClose($hFile) $sTrackLength = __ReadXingFromMP3($sTag) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf EndIf If $fTryNextMethod Then $fTryNextMethod = False If $szExt = ".mp3" Then $sTrackLength = __ReadTLENFromMP3($sTag) If @error Then $fTryNextMethod = True Else $fTryNextMethod = True EndIf EndIf FileClose($hFile) If $fTryNextMethod Then $fTryNextMethod = False ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;receive length of sound $iSndLenMs = __mciSendString("status " & $aSndID[0] & " length", 255) ;assign modified data to variables _TicksToTime($iSndLenMs, $iSndLenHour, $iSndLenMin, $iSndLenSecs) ;assign formatted data to $sSndLenFormat $sTrackLength = StringFormat("%02i:%02i:%02i", $iSndLenHour, $iSndLenMin, $iSndLenSecs) EndIf ; Convert Track_Length to mSec $aiTime = StringSplit($sTrackLength, ":") $iActualTicks = _TimeToTicks($aiTime[1], $aiTime[2], $aiTime[3]) ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;;Get estimated length $iSoundTicks = __mciSendString("status " & $aSndID[0] & " length", 255) ;Compare to actual length 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 Return SetError(0, $iRet, $aSndID) EndFunc ;==>_SoundOpen ;=============================================================================== ; ; Function Name: _SoundClose ; Description:: Closes a sound ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundClose($aSndID) If Not IsArray($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias If __mciSendString("close " & $aSndID[0]) = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundClose ;=============================================================================== ; ; Function Name: _SoundPlay ; Description:: Plays a sound from the current position (beginning is the default) ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; $fWait - If set to 1 the script will wait for the sound to finish before continuing ; - If set to 0 the script will continue while the sound is playing ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 - Failure ; @error = 2 - $fWait is invalid, @error = 1 - play failed ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundPlay($aSndID, $fWait = 0) ;Declare variables Local $iRet, $vTemp ;validate $fWait If $fWait <> 0 And $fWait <> 1 Then Return SetError(2, 0, 0) If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;if sound has finished, seek to start If _SoundPos($aSndID, 2) = _SoundLength($aSndID, 2) Then __mciSendString("seek " & $aSndID[0] & " to start") ;If $fWait = 1 then pass wait to mci If $fWait = 1 Then $iRet = __mciSendString("play " & $aSndID[0] & " wait") Else $iRet = __mciSendString("play " & $aSndID[0]) EndIf ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundPlay ;=============================================================================== ; ; Function Name: _SoundStop ; Description:: Stops the sound ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundStop($aSndID) ;Declare variables Local $iRet, $iRet2, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;seek to start $iRet = __mciSendString("seek " & $aSndID[0] & " to start") ;stop $iRet2 = __mciSendString("stop " & $aSndID[0]) ;return If $iRet = 0 And $iRet2 = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundStop ;=============================================================================== ; ; Function Name: _SoundPause ; Description:: Pauses the sound ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundPause($aSndID) ;Declare variables Local $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;pause sound $iRet = __mciSendString("pause " & $aSndID[0]) ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundPause ;=============================================================================== ; ; Function Name: _SoundResume ; Description:: Resumes the sound after being paused ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundResume($aSndID) ;Declare variables Local $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;resume sound $iRet = __mciSendString("resume " & $aSndID[0]) ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundResume ;=============================================================================== ; ; Function Name: _SoundLength ; Description:: Returns the length of the sound in the format hh:mm:ss ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file, ; $iMode = 1 - hh:mm:ss, $iMode = 2 - milliseconds ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): Length of the sound - Success, 0 and @error = 1 - $iMode is invalid ; Author(s): RazerM, Melba23 ; Mofified: jpm ; ;=============================================================================== ; Func _SoundLength($aSndID, $iMode = 1) ;Declare variables Local $iSndLenMs, $iSndLenMin, $iSndLenHour, $iSndLenSecs, $sSndLenFormat, $vTemp = "" ;validate $iMode If $iMode <> 1 And $iMode <> 2 Then Return SetError(1, 0, 0) If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[3] $aSndID = _SoundOpen($vTemp) EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;receive length of sound $iSndLenMs = __mciSendString("status " & $aSndID[0] & " length", 255) If $aSndID[1] <> 0 Then $iSndLenMs = Round($iSndLenMs / $aSndID[1]) If $vTemp <> "" Then _SoundClose($aSndID) ;if user called _SoundLength with a filename ;assign modified data to variables _TicksToTime($iSndLenMs, $iSndLenHour, $iSndLenMin, $iSndLenSecs) ;assign formatted data to $sSndLenFormat $sSndLenFormat = StringFormat("%02i:%02i:%02i", $iSndLenHour, $iSndLenMin, $iSndLenSecs) ;return correct variable If $iMode = 1 Then Return $sSndLenFormat If $iMode = 2 Then Return $iSndLenMs EndFunc ;==>_SoundLength ;=============================================================================== ; ; Function Name: _SoundSeek ; Description:: Seeks the sound to a specified time ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen (must NOT be a file), $iHour, $iMin, $iSec ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): 1 - Success, 0 and @error = 1 - Failure, ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundSeek(ByRef $aSndID, $iHour, $iMin, $iSec) ;Declare variables Local $iMs = 0, $iRet, $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;prepare mci to receive time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;modify the $iHour, $iMin and $iSec parameters to be in milliseconds ;and add to $iMs $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) $iRet = __mciSendString("seek " & $aSndID[0] & " to " & $iMs) If _SoundPos($aSndID, 2) < 0 Then $aSndID[2] = 0 ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc ;==>_SoundSeek ;=============================================================================== ; ; Function Name: _SoundStatus ; Description:: All devices can return the "not ready", "paused", "playing", and "stopped" values. ; Some devices can return the additional "open", "parked", "recording", and "seeking" values.(MSDN) ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): Sound Status ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundStatus($aSndID) Local $vTemp If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;return status Return __mciSendString("status " & $aSndID[0] & " mode", 255) EndFunc ;==>_SoundStatus ;=============================================================================== ; ; Function Name: _SoundPos ; Description:: Returns the current position of the song ; Parameter(s): $sSndID - Sound ID returned by _SoundOpen or sound file, ; $iMode = 1 - hh:mm:ss, $iMode = 2 - milliseconds ; Requirement(s): AutoIt 3.2 ++ ; Return Value(s): Current Position - Success, @error = 1 - $iMode is invalid ; Author(s): RazerM, Melba23 ; ;=============================================================================== ; Func _SoundPos($aSndID, $iMode = 1) ;Declare variables Local $iSndPosMs, $iSndPosMin, $iSndPosHour, $iSndPosSecs, $sSndPosFormat, $vTemp ;validate $iMode If $iMode <> 1 And $iMode <> 2 Then Return SetError(1, 0, 0) If Not IsArray($aSndID) Then If Not FileExists($aSndID) Then Return SetError(3, 0, 0) ; invalid file/alias $vTemp = FileGetShortName($aSndID) Dim $aSndID[1] = [$vTemp] EndIf If StringInStr($aSndID[0], '!') Then Return SetError(3, 0, 0) ; invalid file/alias ;tell mci to use time in milliseconds __mciSendString("set " & $aSndID[0] & " time format miliseconds") ;receive position of sound $iSndPosMs = __mciSendString("status " & $aSndID[0] & " position", 255) If $aSndID[1] <> 0 Then $iSndPosMs -= $aSndID[2] EndIf ;modify data and assign to variables _TicksToTime($iSndPosMs, $iSndPosHour, $iSndPosMin, $iSndPosSecs) ;assign formatted data to $sSndPosFormat $sSndPosFormat = StringFormat("%02i:%02i:%02i", $iSndPosHour, $iSndPosMin, $iSndPosSecs) ;return correct variable If $iMode = 1 Then Return $sSndPosFormat If $iMode = 2 Then Return $iSndPosMs EndFunc ;==>_SoundPos ;internal functions Func __mciSendString($string, $iLen = 0) Local $iRet $iRet = DllCall("winmm.dll", "int", "mciSendStringA", "str", $string, "str", "", "long", $iLen, "long", 0) If Not @error Then Return $iRet[2] EndFunc ;==>__mciSendString Func __RandomStr($LEN) Local $string For $iCurrentPos = 1 To $LEN $string &= Chr(Random(97, 122, 1)) Next Return $string EndFunc ;==>__RandomStr ;=============================================================================== ; ; Function Name: [private] __ReadTLENFromMP3 ; Description:: Used internally within this file, not for general use ; Parameter(s): $sTag - >= 1024 bytes from 'read raw' mode. ; Requirement(s): File must be an mp3 AFAIK ; Return Value(s): Sound length (hh:mm:ss) - Success, 0 and @error = 1 - Failure ; Author(s): Melba23 ; Modified: RazerM ; ;=============================================================================== ; Func __ReadTLENFromMP3($sTag) Local $iTemp, $sTemp, $iLengthMs, $iLengthHour, $iLengthMin, $iLengthSecs ; Check that an ID3v2.3 tag is present If StringLeft($sTag, 10) <> "0x49443303" Then Return SetError(1, 0, 0) $iTemp = StringInStr($sTag, "544C454E") + 21 $sTag = StringTrimLeft($sTag, $iTemp) $sTemp = "" For $i = 1 To 32 Step 2 If StringMid($sTag, $i, 2) = "00" Then ExitLoop Else $sTemp &= StringMid($sTag, $i, 2) EndIf Next $iLengthMs = Number(_HexToString($sTemp)) If $iLengthMs > 0 Then _TicksToTime($iLengthMs, $iLengthHour, $iLengthMin, $iLengthSecs) ;Convert to hh:mm:ss and return Return StringFormat("%02i:%02i:%02i", $iLengthHour, $iLengthMin, $iLengthSecs) Else Return SetError(1, 0, 0) EndIf EndFunc ;==>__ReadTLENFromMP3 ;=============================================================================== ; ; Function Name: [private] __ReadXingFromMP3 ; Description:: Used internally within this file, not for general use ; Parameter(s): $sTag - first 5156 bytes from 'read raw' mode. ; Requirement(s): File must be an mp3 AFAIK ; Return Value(s): Sound length (hh:mm:ss) - Success, 0 and @error = 1 - Failure ; Author(s): Melba23 ; Modified: RazerM ; ;=============================================================================== ; Func __ReadXingFromMP3($sTag) Local $iXingPos, $iFlags, $iFrames, $sHeader, $iMPEGByte, $iFreqByte, $iMPEGVer, $iLayerNum, $iSamples, $iFreqNum, $iFrequency, $iLengthMs, $iLengthHours, $iLengthMins, $iLengthSecs $iXingPos = StringInStr($sTag, "58696E67") If $iXingPos = 0 Then Return SetError(1, 0, 0) ; Read fields flag $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 $sHeader = StringMid($sTag, $iXingPos - 72, 8) ; Read the relevant bytes $iMPEGByte = Number("0x" & StringMid($sHeader, 4, 1)) $iFreqByte = Number("0x" & StringMid($sHeader, 6, 1)) ; Decode them ; 8 = MPEG-1, 0 = MPEG-2 $iMPEGVer = BitAND($iMPEGByte, 8) ; 2 = Layer III, 4 = Layer II, 6 = Layer I $iLayerNum = BitAND($iMPEGByte, 6) 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 $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 $iLengthMs = Int(($iFrames * $iSamples / $iFrequency) * 1000) ; Convert to hh:mm:ss and return _TicksToTime($iLengthMs, $iLengthHours, $iLengthMins, $iLengthSecs) Return StringFormat("%02i:%02i:%02i", $iLengthHours, $iLengthMins, $iLengthSecs) EndFunc ;==>__ReadXingFromMP3Changes:Changed order of sound-length methods.Optimised routine for TLEN and Xing by only reading in data once.Some bug fixes.Edit: Updated with a few minor bug fixes outlined by Melba23 Edited October 10, 2008 by RazerM My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop. Link to comment Share on other sites More sharing options...
Bert Posted October 10, 2008 Share Posted October 10, 2008 ummm, did you ever look at what asbeer450 came up with? just curious..http://www.autoitscript.com/forum/index.ph...st&id=21742 The Vollatran project  My blog: http://www.vollysinterestingshit.com/ Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 10, 2008 Moderators Share Posted October 10, 2008 ummm, did you ever look at what asbeer450 came up with? just curious..http://www.autoitscript.com/forum/index.ph...st&id=21742Hi,Yes, I have looked at these functions - and very comprehensive they are. However, they are also very complex and perhaps a little OTT if you are only looking to control the volume of your own application.Using SoundSetWaveVolume works very well in Vista, as long as you only try to control your own application, while the MCI version works well in Win98 as well as Vista (I do not have access to any other OS). These 2 ways to control your own application are simple and small. The Sound UDF seems to me to be aimed at those who want to write their own application to play music files - the SoundGetSetQuery UDF is more for those who are looking for considerably more control over the Windows volume settings.Please do not think I am being uncomplimentary to SoundGetSetQuery and its author - far from it. I just feel that its use for controlling the volume in your own application is a bit "sledgehammer to crack a nut"!M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 10, 2008 Moderators Share Posted October 10, 2008 RazerM, Small bug in the TLEN part of the latest beta. Line 503: $iLengthMs = Number($sTemp) should read $iLengthMs = Number(_HexToString($sTemp)). Otherwise it is directly converting the ASCII codes into decimal, which gives a rather larger number than the one we are looking for - i.e.: 89897:35:30 in place of 00:04:21!!! I also feel that the size of the tag used to look for TLEN should be increased. Looking at my son's mp3 library, it sems the ID3 tag can be much larger than those I found in my own collection and, as the use of TLEN is be very much the last opportunity to get a correct VBR timing, I feel we should give it as much of a chance as possible. So I would remove line 486: $sTag = StringLeft($sTag, 1024) and search the whole 5156 byte file read. The added overhead for a single search must be minimal and, if we get to this point, we really need to find the TLEN field! Other than the small bug above, the latest version looks good so far. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
RazerM Posted October 10, 2008 Author Share Posted October 10, 2008 Thanks Melba23, I've updated post #47 with the changes mentioned in the post above. My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 11, 2008 Moderators Share Posted October 11, 2008 RazerM, I have tested the new beta on every mp3 I have, in both Vista (where it uses file properties each time) and Win98 (where it uses a mix of Xing, TLEN and MCI depending on the file) and it has produced the correct duration (disregarding the inherent 1 second tolerance) each time. As far as I am concerned it is good to go. Did you consider adding the volume function? Look forward to seeing a new UDF issued soon. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
RazerM Posted October 11, 2008 Author Share Posted October 11, 2008 (edited) Sounds great. About the volume function, only vcr and digitalvideo devices 'officially' support the 'setaudio <etc>' command. (from MSDN docs) Therefore I'm not sure it's good practise to add it in as we are dealing with waveform-audio devices. I'll submit the sound.au3 for release in next beta, and the volume function can be on hold until we discuss it more. Edited October 11, 2008 by RazerM My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted October 11, 2008 Moderators Share Posted October 11, 2008 RazerM, Quite understand your concern over the volume code. I was quite surprised myself when it worked! I had been using the SoundGetSetQuery UDF that Volly referred to as volume control in Win98, but I thought I would give the MCI call a chance. I was even more surprised when it worked in Vista, although I intend to use the built-in SoundSetWaveVolume function as standard for the moment. Fingers crossed that the new Sound UDF is accepted for the next beta release. It has been a pleasure working with you - hope we can do it again some time. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
Madza91 Posted November 8, 2008 Share Posted November 8, 2008 (edited) Hello, this is good but I replaced this Sound UDF with default AutoIt and now not works this Func for Volume: Func _SoundVolume($sSnd_id, $Volume); $Volume: 0 - 1000, 1000= normal ;Declare variables Local $iRet If StringInStr($sSnd_id,'!') Then Return SetError(3, 0, 0); invalid file/alias if $Volume < 0 or $Volume > 1000 Then Return SetError(1, 0, 0) $iRet = mciSendString("setaudio " & FileGetShortName($sSnd_id) & " volume to "&$Volume) ;return If $iRet = 0 Then Return 1 Else Return SetError(1, 0, 0) EndIf EndFunc;==>_SoundVolume How to make this to work with ?! Edit: Sounds great. About the volume function, only vcr and digitalvideo devices 'officially' support the 'setaudio <etc>' command. (from MSDN docs) Therefore I'm not sure it's good practise to add it in as we are dealing with waveform-audio devices. I'll submit the sound.au3 for release in next beta, and the volume function can be on hold until we discuss it more. I didn't sew this... Than, when will be volume function finished? ^^ Edited November 8, 2008 by n3nE [quote name='dbzfanatic' post='609696' date='Nov 26 2008, 08:46 AM']This is a help forum not a "write this for me" forum.[/quote](Sorry for bad English) :) Link to comment Share on other sites More sharing options...
Seeker Posted December 30, 2008 Share Posted December 30, 2008 Hi! I can not get sound length on W2K Server or in W2003Server. Why? Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 30, 2008 Moderators Share Posted December 30, 2008 (edited) m_havo, A number of questions to try and answer yours! 1. Sound first tries to get the duration property from the shell.application object. If you look at the properties of an mp3 file in Explorer, does it give a duration? We know that it does in XP and Vista, and does not in Win98 and Win2k. So I would not expect Win2kServer to work, and perhaps Win2003 Server is also lacking this information. If you could run the following code with both OSes and post the resulting text from the SciTE console, it would confirm the diagnosis:expandcollapse popup#NoTrayIcon #include <Array.au3> #include <File.au3> $hDebugFile = FileOpen(@DesktopDir & "\SoundTest.txt", 2) $sFile = FileOpenDialog("Open MP3 File", @MyDocumentsDir, "MP3 Files (*.mp3)") If @error Then ConsoleWrite("ERR: No File Opened" & @CRLF) Exit EndIf Local $szDrive, $szDir, $szFName, $szExt;$szExt is ".mp3" anyway _PathSplit($sFile, $szDrive, $szDir, $szFName, $szExt) $Dir_Name = $szDrive & $szDir $File_Name = $szFName & $szExt $DOS_Dir = FileGetShortName($Dir_Name, 1) $ShellApp = ObjCreate("shell.application") If IsObj($ShellApp) Then $Dir = $ShellApp.NameSpace ($DOS_Dir) If IsObj($Dir) Then $File = $Dir.Parsename ($File_Name) If IsObj($File) Then $sRaw = $Dir.GetDetailsOf ($File, -1) ConsoleWrite("RAW--------------------------" & @CRLF & $sRaw & @CRLF & "END--------------------------" & @CRLF) $aInfo = StringRegExp($sRaw, "Duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})", 3) If Not IsArray($aInfo) Then ConsoleWrite("ERR: $aInfo Not Array") Exit EndIf ConsoleWrite("$aInfo = [" & _ArrayToString($aInfo, ",") & "]" & @CRLF) $Track_Length = $aInfo[0] ConsoleWrite("$Track_Length = '" & $Track_Length & "'" & @CRLF) EndIf EndIf EndIf FileClose($hDebugFile) MsgBox(262144, "Done", "Thanks for testing.") Edited December 30, 2008 by Melba23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted July 7, 2010 Moderators Share Posted July 7, 2010 Hi all,A recent thread highlighted a small problem with the soundfiles in the Windows\Media folder in Vista and Win7 when using _SoundPlay with the filename as a parameter.Basically these files, which all have spaces in their long names (e.g. C:\Windows\Media\Windows Ding.wav) do not have a short name (ie the old 8.3 format) from Vista onwards - a call to FileGetShortName returns the full name. As a result the DLL calls within _SoundPlay are made with a space in the string parameter and so fail. Experimentation has shown that only one call to the relevant DLL will accept spaces - and that is the one used by _SoundOpen. So to play these files with Sound.au3 you need to make a small modification to the _SoundOpen function as follows:; This line in _SoundOpen (it is line 79 in the latest version): __SoundMciSendString("open " & FileGetShortName($sFile) & " alias " & $aSndID[0]) ; needs to be changed to: __SoundMciSendString("open """ & $sFile & """ alias " & $aSndID[0])Now _SoundOpen will open the file despite the spaces in the name and the returned array can be used in all the other _Sound* functions without problem. Trac ticket #1707 has been opened to get this fix added to the next release, but if you feel you really need it, you now have the info to do it yourselves.You can play also these sound files with the built-in SoundPlay command without problem, which given their short duration and the unlikely need to use any of the other _Sound* functions on them , may well be the easiest solution.Happy to answer any queries to the best of my ability. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
wakillon Posted September 28, 2010 Share Posted September 28, 2010 (edited) @Melba23For Info i'm on xp sp3.I corrected sound.au3 like you say, but no result !I have tried with short path _SoundPlay ( "C:\38.mp3", 1 ) and SoundPlay ( "C:\38.mp3", 1 ) but no result too...Thanks for your advices ! Edited September 28, 2010 by wakillon AutoIt 3.3.14.2 X86 - SciTE 3.6.0 - WIN 8.1 X64 - Other Example Scripts Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted September 28, 2010 Moderators Share Posted September 28, 2010 wakillon,The error only occurred on Vista/Win7 as explained in the above post, so as you are on XP there was no need to amend the UDF. But it does no harm to have done so - and the next release will have the modified files anyway! Once I had gone through all the hoops that Vista demands to get a file into the C:\ root, I can play mp3 files from there quite happily. The fact that you cannot use the built-in SoundPlay either makes me think that the error is not within Sound.au3. However, could you please try and open the troublesome mp3 file with _SoundOpen and let me know what you get in @error and @extended. That will at least give us some idea why you cannot open the file. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
wakillon Posted September 28, 2010 Share Posted September 28, 2010 (edited) @MelbaSorry i don't post to the right topic !Here is the good one with screenshot of the return error ! Edited September 28, 2010 by wakillon AutoIt 3.3.14.2 X86 - SciTE 3.6.0 - WIN 8.1 X64 - Other Example Scripts Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now