 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 6:51 pm Post subject: Recording Audio Seven Ways in AHK (6 ways even work) |
|
|
Audio recording is not built into AHK. To record audio we must use external programs. That is the focus of this collection of scripts.
I wanted to explore different ways to record audio with AHK. Three are stand-alone programs that either come with Windows (SndRec32.exe and SoundRecorder.exe) or are an open source project (Audacity.exe). The MCI is a part of Windows and the last three tools are open-source APIs for audio development (SoX.DLL, FMOD.DLL and BASS.DLL)
I used existing AHK libraries where possible (MCI and BASS) and wrote my own libraries where none existed (SndRec32, SoundRecorder, FMOD, SoX). (NOTE!: I am NOT any kind of expert on writing libraries. Please help me make these better if you can. Please!)
One of the tools (FMOD) I am not able to get working as a recorder yet. FMOD is definitely able to support recording, but I haven't found the right code to make it work. I do have playback working in FMOD and included it in my script. Any help with FMOD would be appreciated!!!
My plan was to write a simple audio recorder AHK GUI with these two basic functions: Record/Pause and Save/Exit. I would use the same basic GUI for each tool. A library of functions would link the GUI to each program in a (fairly) standard way. What follows is a synopsis of the recording tools with a GUI script and a library script for each.
I did this as a learning exercise, so suggestions for any of the scripts would be very welcome.
Last edited by fredinga on Sun Jan 24, 2010 11:56 pm; edited 1 time in total |
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 6:58 pm Post subject: |
|
|
Audacity is a cross-platform, open-source audio editor and recorder. You can download it from audacity.sourceforege.net. You only need the audacity.exe file in your script subdirectory.
From my script you can run Audacity so it is visible along with the GUI or completely hide it.
Here is my AHK library script:
| Code: |
;*********************
; AUD.AHK Library *
; vers 0.0.1 *
; by FredInGA *
; Forum #53673 *
;*********************
AUD_Open(View) {
global
IfNotExist, audacity.exe
{
Msgbox,4096,Whoops!, Cannot find
Audacity.exe!`n`nPlease make sure Audacity.exe is located
in the script folder.
ExitApp
}
Run, audacity,,%View%,AUDpid
return AUDpid
}
AUD_Record() {
ControlClick, wxWindowClass4, ahk_class
wxWindowClass
return 1
}
AUD_Play() {
ControlClick, wxWindowClass3, ahk_class
wxWindowClass
return 0
}
AUD_Pause() {
ControlClick, wxWindowClass5, ahk_class
wxWindowClass
return 2
}
AUD_Stop() {
ControlClick, wxWindowClass6, ahk_class
wxWindowClass
sleep, 1000
return 2
}
AUD_Begin() {
ControlClick, wxWindowClass2, ahk_class
wxWindowClass
return 0
}
AUD_End() {
ControlClick, wxWindowClass7, ahk_class
wxWindowClass
return 0
}
AUD_Exit() {
WinClose, ahk_class wxWindowClass
return 0
}
|
And here is my GUI script:
| Code: |
; recordAUD.AHK by fredinga
; Forum #53673
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include AUD.AHK
;open with "MIN", "MAX", "HIDE" or "" (normal size)
AUD_Open("HIDE")
SetTimer showRecording,350
SetTimer showRecording,Off
Recorded = 0
Paused = 0
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record/Pause
gui Add,Button, wp h25 gExit, Exit (Save as .AUP)
Gui, Add, StatusBar,, Ready
gui, Show,,Audacity
WinMove, Audacity,, 860, 280
Return
Record:
if (Recorded = 0) {
Recorded = 1
status := AUD_Record()
SetTimer showRecording,On
gosub, showRecording
} else {
if (Paused = 0) {
Paused = 1
SetTimer showRecording,Off
SB_SetText(" Paused")
status := AUD_Pause()
} else {
Paused = 0
SetTimer showRecording,On
gosub, showRecording
status := AUD_Pause()
}
}
return
showRecording:
Step ++
if (Step = 1)
SB_SetText("Recording")
else if (Step = 2)
SB_SetText("
Recording")
else {
SB_SetText("
Recording")
Step = 0
}
return
ESC::
Exit:
GUIClose:
SetTimer showRecording,Off
SB_SetText(" Closing")
AUD_Stop()
AUD_Exit()
ExitApp
return
|
|
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 7:05 pm Post subject: |
|
|
SndRec32 in WindowsXP and earlier versions of Windows
Microsoft introduced the SndRec32 accessory in the early versions of Windows. It is a sound recorder/player with a ~60 second time limit and five control buttons. I used the script by TLM (www.autohotkey.com/forum/viewtopic.php?t=46453) as the starting point for my script.
I wrote a simple interface library (SRXP.AHK) to allow AHK to control the sound recorder even when it is "hidden", i.e. running but not visible on the screen. The library is probably overkill, but it let me write the GUI in a way that is consistent with my other examples.
Here is my AHK library script:
| Code: |
;*********************
; SRXP.AHK Library
; vers 0.0.1
; by FredInGA
; Forum #53673
;*********************
SRXP_Open(View) {
global
IfNotExist, %A_WinDir%\system32\sndrec32.exe
{
Msgbox,4096,Whoops!, Cannot find Microsoft Sound Recorder!`n`nPlease make sure sndrec32.exe is located in:`n`n*Drive*:\WINDOWS\System32
ExitApp
}
Run, sndrec32,,%View%,SRXPpid
return SRXPpid
}
SRXP_Record() {
ControlClick, Button5, ahk_class SoundRec,
return 1
}
SRXP_Stop() {
ControlClick, Button4, ahk_class SoundRec,
return 0
}
SRXP_Play() {
ControlClick, Button3, ahk_class SoundRec,
return 2
}
SRXP_Begin() {
ControlClick, Button1, ahk_class SoundRec,
return 0
}
SRXP_End() {
ControlClick, Button2, ahk_class SoundRec,
return 0
}
SRXP_Exit() {
WinClose, ahk_class SoundRec
return 0
}
|
And here is my GUI script:
| Code: |
; recordSRXP.AHK by fredinga
; Forum #53673
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include SRXP.AHK
;open with "MIN", "MAX", "HIDE" or "" (normal size)
SRXP_Open("HIDE")
SetTimer showRecording,350
SetTimer showRecording,Off
Recording = 0
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record/Pause
gui Add,Button, wp h25 gExit, Exit (Save)
Gui, Add, StatusBar,, Ready
gui, Show,,Sound Recorder XP
Return
Record:
if (Recording = 0) {
Recording = 1
status := SRXP_Record()
SetTimer showRecording,On
gosub, showRecording
} else {
Recording = 0
status := SRXP_Stop()
SetTimer showRecording,Off
SB_SetText(" Paused")
}
return
showRecording:
Step ++
if (Step = 1)
SB_SetText("Recording")
else if (Step = 2)
SB_SetText(" Recording")
else {
SB_SetText(" Recording")
Step = 0
}
return
ESC::
Exit:
GUIClose:
SRXP_Stop()
SetTimer showRecording,Off
SB_SetText(" Saving")
SRXP_Exit()
SetTimer showRecording,Off
SB_SetText(" Closing")
ExitApp
return
|
Note: You can copy the file SndRec32.exe from an XP machine into the Windows\System32 folder on a Vista or Win7 machine and it will work just fine. |
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 7:11 pm Post subject: |
|
|
SoundRecorder in Windows Vista and Windows 7
Microsoft introduced the SoundRecorder accessory in Vista. It was said to be an improvement on the older SndRec32 accessory in earlier versions of Windows.accessory in earlier versions of Windows. It does not include a player and has only a single button for controlling recording. It is much more complicated to resume recording in this new sound recorder version. It has the ~60 second recording limit like the earlier Windows sound recorder.
You can run SoundRecorder so it is visible along with the GUI or completely hide it.
Here is my AHK library script:
| Code: |
;*********************
; SRW7.AHK Library
; vers 0.0.1
; by FredInGA
; Forum #53673
;*********************
;SoundRecorder Docs: http://
SRW7_Open(View) {
global
IfNotExist, %A_WinDir%\system32\soundrecorder.exe
{
Msgbox,4096,Whoops!, Cannot find Microsoft Sound Recorder!`n`nPlease make sure soundrecorder.exe is located in:`n`n*Drive*:\WINDOWS\System32
ExitApp
}
Run, %A_WinDir%\system32\soundrecorder,,%View%,SRW7pid
return SRW7pid
}
SRW7_Record() {
ControlClick, ToolbarWindow324, ahk_class AudioRecorderMainFrameTraits
return 1
}
SRW7_Stop() {
ControlClick, ToolbarWindow323, ahk_class AudioRecorderMainFrameTraits
return 0
}
SRW7_Exit() {
WinClose, ahk_class AudioRecorderMainFrameTraits
return 0
}
|
And here is my GUI script:
| Code: |
; recorderSRW7 by fredinga
; Forum # 53673
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include SRW7.AHK
;open with "MIN", "MAX", "HIDE" or "" (normal size)
SRW7_Open("HIDE")
SetTimer showRecording,350
SetTimer showRecording,Off
Recording = 0
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record
gui Add,Button, wp h25 gExit, Exit (Save as .WMA)
Gui, Add, StatusBar,, Ready
gui, Show,,Sound Recorder Windows 7
Return
Record:
if (Recording = 0) {
status := SRW7_Record()
SetTimer showRecording,On
gosub, showRecording
Recording = 1
}
return
showRecording:
Step ++
if (Step = 1)
SB_SetText("Recording")
else if (Step = 2)
SB_SetText(" Recording")
else {
SB_SetText(" Recording")
Step = 0
}
return
ESC::
Exit:
GUIClose:
status := SRW7_Stop()
SB_SetText(" Saving")
SRW7_Exit()
ExitApp
return
|
Note: The SoundRecorder.exe program only works on Vista and Win7 machines. |
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 7:15 pm Post subject: |
|
|
Windows with MCI
Quoting Microsoft at msdn.microsoft.com/en-us/library/ms710984(VS.85).aspx
"The Media Control Interface (MCI) provides standard commands for playing multimedia devices and recording multimedia resource files. These commands are a generic interface to nearly every kind of multimedia device.
MCI supports Command Strings and Command Messages. You can use either strings or messages, or both, in your MCI application."
I used the MCI library found at www.autohotkey.com/forum/viewtopic.php?t=35266 and modified jballi's GUI script to write my GUIs. This was my
starting point for all of the tools that follow. You don't need any external files to use MCI.
Here is the AHK library script by jballi:
| Code: |
;- v0.3.1
;*********************
;* *
;* *
;* MCI *
;* *
;* *
;*********************
/*
Each MCI function is documented separately. The following is general
information that relates to the entire library.
Notes
=====
MCI Reference Guide:
http://msdn.microsoft.com/en-us/library/ms709461(VS.85).aspx
Devices referenced within the function documentation:
Driver Type Description
------ ---- -----------
MCIAVI avivideo
MCICDA cdaudio CD audio
dat Digital-audio tape player
digitalvideo Digital video in a window (not GDI-based)
MPEGVideo General-purpose media player
other Undefined MCI device
overlay Overlay device (analog video in a window)
scanner Image scanner
MCISEQ sequencer MIDI sequencer
vcr Video-cassette recorder or player
MCIPIONR videodisc Videodisc (Pioneer LaserDisc)
MCIWAVE waveaudio Audio device that plays digitized waveform
files
Programming Notes
=================
OutputDebug statements in the core of some of the functions that only execute
on condition are permanent and are provided to help the developer find and
eliminate programming errors. Under normal conditions, these debugging
statements should not slow down the operation of the functions because they
"should" only execute when the developer has made a programming/logic error or
if there are unusual conditions.
Credit
======
- Original library released by Fincs as the "Sound_*" library and then as the
"Media_*" library. The orginal libraries are a conversion-to-AutoHotkey
from the AutoIt "Sound.au3" standard library written by RazerM.
This library would not be possible without the significant effort by
Fincs to translate and enhance the original library and RazerM for providing
the original AutoIt library. Some of the code and documentation are from
the libraries provided by Fincs:
Post 1: http://www.autohotkey.com/forum/viewtopic.php?t=20666
Post 2: http://www.autohotkey.com/forum/viewtopic.php?t=22662
- Notify idea and code from Sean:
Post: http://www.autohotkey.com/forum/viewtopic.php?p=132331#132331
- mciGetErrorString DLL function code from PhiLho:
Post: http://www.autohotkey.com/forum/viewtopic.php?p=116011#116011
*/
;----------
;
; Function: MCI_Open
;
;
; Description:
;
; Opens an MCI device and loads the specified file (p_MediaFile).
;
;
; Parameters:
;
; p_MediaFile - A multimedia file. [Required]
;
; p_Alias - Alias [Optional]. A name such as media1. If blank, an
; alias will automatically be generated.
;
; p_Flags - Flags that determine how the device is opened. [Optional]
;
; Some commonly used flags include the following:
;
; type {device_type}
; sharable
;
; If more than one flag is used, separate each flag/flag value with a
; space. For example:
;
; type MPEGVideo sharable
;
; Notes
; -----
; - The "wait" flag is automatically added to the end of the
; command string. This flag directs the device to complete the
; "open" request before returning.
;
;
; - By default, the MCI device that is opened is determined by the
; file's extension. The "type" flag can be used to 1) override
; the default device that is registered for the file extension or
; to 2) open a media file with a file extension that is not
; registered as a MCI file extension.
;
; To see a list of MCI devices that have been registered for your
; computer, go the following registry locations:
;
; Windows NT4/2000/XP/2003/Vista/etc.:
;
; 16-bit:
; HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI
;
; 32-bit:
; HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI32
;
;
; Windows 95/98/ME:
;
; HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\MCI
;
;
; To see a list of registered file extensions and the MCI device
; that has been assigned to each extension, go the following
; locations:
;
; For Windows NT4/2000/XP/2003/Vista, this information is
; stored in the registry at the following location:
;
; HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions
;
;
; For Windows 95/98/ME, this information is stored in the
; %windir%\win.ini file in the "MCI Extensions" section.
;
;
; - Use the "shareable" flag with care. Per msdn, the "shareable"
; flag "initializes the device or file as shareable. Subsequent
; attempts to open the device or file fail unless you specify
; "shareable" in both the original and subsequent open commands.
; MCI returns an invalid device error if the device is already
; open and not shareable. The MCISEQ sequencer and MCIWAVE
; devices do not support shared files."
;
;
; - For a complete list of flags and descriptions for the "open"
; command string, see the "MCI Reference Guide" (link at the top
; of this library).
;
;
; Return value:
;
; Returns the multimedia handle (alias) or a 0 to indicate failure.
; Failure will occur with any of the following conditions:
;
; - The media file does not exist.
;
; - The media file's extension is not a regisitered MCI extension.
; Note: This test is only performed if the "type" flag is not
; specified.
;
; - Non-zero return code from the MCI_SendString function.
;
;
; Remarks:
;
; - Use the MCI_OpenCDAudio function to open a CDAudio device.
;
; - After the device has been successfully opened, this function sets the
; time format to milliseconds. This time format will remain in effect
; until it is manually set to another value or until the device is
; closed.
;
;------------------------------------------------------------------------------
MCI_Open(p_MediaFile,p_Alias="",p_Flags="")
{
Static s_Seq=0
;[==============]
;[ Parameters ]
;[==============]
;-- p_MediaFile
if p_MediaFile<>new
{
;-- Media file exist?
IfNotExist %p_MediaFile%
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: The media file can't be
found. Return=0
)
return false
}
;-- "Type" flag not defined?
if InStr(A_Space . p_Flags . A_Space," type ")=0
{
;-- Registered file extension?
SplitPath p_MediaFile,,,l_Extension
;-- Which OS type?
if A_OSType=WIN32_NT ;-- Windows NT4/2000/XP/2003/Vista
RegRead
,l_Dummy
,HKEY_LOCAL_MACHINE
,SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions
,%l_Extension%
else
{
;-- Windows 95/98/ME
iniRead
,l_Value
,%A_WinDir%\win.ini
,MCI Extensions
,%l_Extension%
if l_Value=ERROR
ErrorLevel=1
}
;-- Not found?
if ErrorLevel
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: The file extension for this media
file is not registered as a valid MCI extension. Return=0
)
return false
}
}
;-- Enclose in DQ
p_MediaFile="%p_MediaFile%"
}
;-- Alias
if p_Alias is Space
{
s_Seq++
p_Alias=MCIFile%s_Seq%
}
;[===============]
;[ Open device ]
;[===============]
l_CmdString=open %p_MediaFile% alias %p_Alias% %p_Flags% wait
l_Return:=MCI_SendString(l_CmdString,Dummy)
if l_Return
l_Return:=0
else
l_Return:=p_Alias
;-- Set time format to milliseconds
if l_Return
{
l_CmdString=set %p_Alias% time format milliseconds wait
MCI_SendString(l_CmdString,Dummy)
}
;-- Return to sender
return l_Return
}
;----------
;
; Function: MCI_OpenCDAudio
;
;
; Description:
;
; Opens a CDAudio device.
;
;
; Parameters:
;
; p_Drive - CDROM drive letter. [Optional] If blank, the first CDROM
; drive found is used.
;
; p_Alias - Alias. [optional] A name such as media1. If blank, an
; alias will automatically be generated.
;
; p_CheckForMedia - Check for media [Optional]. The default is TRUE.
;
;
; Return value:
;
; Returns the multimedia handle (alias) or a 0 to indicate failure.
; Failure will occur with any of the following conditions:
; - The computer does not have a CDROM drive.
; - The specified drive is not CDROM drive.
; - Non-zero return code from the MCI_SendString function.
;
; If p_CheckForMedia is TRUE (the default), failure will also occur with
; any of the following conditions:
; - No media was found in the device.
; - Media does not contain audio tracks.
;
;
; Remarks:
;
; After the device has been successfully opened, this function sets
; the time format to milliseconds. This time format will remain in effect
; until it is manually set to another value or until the device is closed.
;
;------------------------------------------------------------------------------
MCI_OpenCDAudio(p_Drive="",p_Alias="",p_CheckForMedia=true)
{
Static s_Seq=0
;-- Parameters
p_Drive=%p_Drive% ;-- Autotrim
p_Drive:=SubStr(p_Drive,1,1)
if p_Drive is not Alpha
p_Drive:=""
;-- Drive not specified
if p_Drive is Space
{
;-- Collect list of CDROM drives
DriveGet l_ListOfCDROMDrives,List,CDROM
if l_ListOfCDROMDrives is Space
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: This PC does not have functioning CDROM
drive. Return=0
)
return false
}
;-- Assign the first CDROM drive
p_Drive:=SubStr(l_ListOfCDROMDrives,1,1)
}
;-- Is this a CDROM drive?
DriveGet l_DriveType,Type,%p_Drive%:
if l_DriveType<>CDROM
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: The specified drive (%p_Drive%:) is not
a CDROM drive. Return=0
)
return false
}
;-- Alias
if p_Alias is Space
{
s_Seq++
p_Alias=MCICDAudio%s_Seq%
}
;-- Open device
l_CmdString=open %p_Drive%: alias %p_Alias% type cdaudio shareable wait
l_Return:=MCI_SendString(l_CmdString,Dummy)
if l_Return
l_Return:=0
else
l_Return:=p_Alias
;-- Device is open
if l_Return
{
;-- Set time format to milliseconds
l_CmdString=set %p_Alias% time format milliseconds wait
MCI_SendString(l_CmdString,Dummy)
;-- Check for media?
if p_CheckForMedia
{
if not MCI_MediaIsPresent(p_Alias)
{
MCI_Close(p_Alias)
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: Media is not present in the
specified drive (%p_Drive%:). Return=0
)
return false
}
;-- 1st track an audio track?
if not MCI_TrackIsAudio(p_Alias,1)
{
MCI_Close(p_Alias)
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: Media in drive %p_Drive%: does not
contain CD Audio tracks. Return=0
)
return false
}
}
}
return l_Return
}
;----------
;
; Function: MCI_Close
;
;
; Description:
;
; Closes the device and any associated resources.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Remarks:
;
; Closing a device usually stops playback but not always. Consider
; stopping the device before closing it.
;
;
;
;------------------------------------------------------------------------------
MCI_Close(p_lpszDeviceID)
{
Static MM_MCINOTIFY:=0x03B9
;-- Close device
l_Return:=MCI_SendString("close " . p_lpszDeviceID . " wait",Dummy)
;-- Turn off monitoring of MM_MCINOTIFY message?
if OnMessage(MM_MCINOTIFY)="MCI_Notify"
{
;-- Don't proceed unless all MCI devices are closed
MCI_SendString("sysinfo all quantity open",l_OpenMCIDevices)
if l_OpenMCIDevices=0
{
;-- Disable monitoring
OnMessage(MM_MCINOTIFY,"")
}
}
return l_Return
}
;----------
;
; Function: MCI_Play
;
;
; Description:
;
; Starts playing a device.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Flags - Flags that determine how the device is played. [Optional]
; If blank, no flags are used.
;
; Some commonly used flags include the following:
;
; from {position}
; to {position}
; wait
;
; If more than one flag is used, separate each flag/flag value with a
; space. For example:
;
; from 10144 to 95455 wait
;
; Notes
; -----
; - With the exception of very short sound files (<300 ms), the
; "wait" flag is not recommended. The entire application will be
; non-responsive while the media is being played.
;
; - Do not add the "notify" flag unless you plan to have your
; script trap the MM_MCINOTIFY message outside of this function.
; The "notify" flag is automatically added if the p_Callback
; parameter contains a value.
;
; - For a complete list of flags and descriptions for the "play"
; command string, see the "MCI Reference Guide" (link at the top
; of this library).
;
;
; p_Callback - Function name that is called when the MM_MCINOTIFY message
; is sent. [Optional]. If defined, the "notify" flag is automatically
; added.
;
; Important: The syntax of this parameter and the associated function
; is critical. If not defined correctly, the script may crash.
;
; The function must have at least one parameter. For example:
;
; MyNotifyFunction(NotifyFlag)
;
; Additional parameters are allowed but they must be optional (contain
; a default value). For example:
;
; MyNotifyFunction(NotifyFlag,FirstCall=false,Parm3="ABC")
;
; When a notify message is sent, the approriate MM_MCINOTIFY flag is
; sent to the developer-defined function as the first parameter. See
; the MCI_Notify function for a description and a list of MM_MCINOTIFY
; flag values.
;
;
; p_hWndCallback - Handle to a callback window if the p_Callback
; parameter contains a value and/or if the "notify" flag is defined
; [Optional]. If undefined but needed, the handle to default
; Autohotkey window is used.
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;------------------------------------------------------------------------------
MCI_Play(p_lpszDeviceID,p_Flags="",p_Callback="",p_hwndCallback=0)
{
Static MM_MCINOTIFY:=0x03B9
;-- Build command string
l_CmdString:="play " . p_lpszDeviceID
if p_Flags
l_CmdString:=l_CmdString . A_Space . p_Flags
;-- Notify
p_Callback=%p_Callback% ;-- AutoTrim
if StrLen(p_Callback)
{
l_CmdString:=l_CmdString . " notify"
;-- Attach p_Callback to MCI_Notify function
MCI_Notify(p_Callback,"","","")
;-- Monitor for MM_MCINOTIFY message
OnMessage(MM_MCINOTIFY,"MCI_Notify")
;-- Note: If the MM_MCINOTIFY message was monitored elsewhere,
; this statement will override it.
}
;-- Callback handle
if not p_hwndCallback
{
if InStr(A_Space . l_CmdString . A_Space," notify ")
or StrLen(p_Callback)
{
l_DetectHiddenWindows:=A_DetectHiddenWindows
DetectHiddenWindows On
Process Exist
p_hwndCallback:=WinExist("ahk_pid " . ErrorLevel . " ahk_class AutoHotkey")
DetectHiddenWindows %l_DetectHiddenWindows%
}
}
;-- Send it!
l_return:=MCI_SendString(l_CmdString,Dummy,p_hwndCallback)
return l_Return
}
;----------
;
; Function: MCI_Notify (Internal function. Do not call directly). ;-- Experimental
;
;
; Description:
;
; This function has 2 responsibilties:
;
; 1) If called by the MCI_Play function, wParam contains the name of the
; developer-defined function. This value is assigned to the
; s_Callback static variable for future use.
;
; 2) When called as a result of MM_MCINOTIFY message, this function will
; call the developer-defined function (name stored in the s_Callback
; static variable) sending the MM_MCINOTIFY status flag as the first
; parameter.
;
;
; Parameters:
;
; wParam - Function name or a MM_MCINOTIFY flag. MM_MCINOTIFY flag
; values are as follows:
;
; MCI_NOTIFY_SUCCESSFUL=0x1
; The conditions initiating the callback function have been
; met.
;
; MCI_NOTIFY_SUPERSEDED=0x2
; The device received another command with the "notify" flag
; set and the current conditions for initiating the callback
; function have been superseded.
;
; MCI_NOTIFY_ABORTED=0x4
; The device received a command that prevented the current
; conditions for initiating the callback function from being
; met. If a new command interrupts the current command and
; it also requests notification, the device sends this
; message only and not MCI_NOTIFY_SUPERSEDED.
;
; MCI_NOTIFY_FAILURE=0x8
; A device error occurred while the device was executing the
; command.
;
; lParam - lDevID. This is the identifier of the device initiating the
; callback function. This information is only useful if operating
; more than one MCI device at a time.
;
;
; Return value:
;
; Per msdn, returns 0 to indicate a successful call.
;
;
; Remarks:
;
; This function does not complete until the call to the developer-defined
; function has completed. If a MM_MCINOTIFY message is issued while this
; function is running, the message will be treated as unmonitored.
;
;------------------------------------------------------------------------------
MCI_Notify(wParam,lParam,msg,hWnd)
{
;;;;; Critical
;-- This will cause MM_MCINOTIFY messages to be buffered rather than
; discared if this function is still running when another MM_MCINOTIFY
; message is sent.
Static s_Callback
;-- Internal call?
if lParam is Space
{
s_Callback:=wParam
return
}
;-- Call developer function
if s_Callback is not Space
%s_Callback%(wParam)
return 0
}
;----------
;
; Function: MCI_Stop
;
;
; Description:
;
; Stops playback or recording.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Remarks:
;
; - After close, a "seek to start" is not done because 1) it slows down the
; the stop request and 2) it may be unwanted. If you need to set the
; media position back to the beginning after a stop, call the MCI_Seek
; function and set the p_Position parameter to 0.
;
; - For (some) CD audio devices, the stop command stops playback and resets
; the current track position to zero.
;
;------------------------------------------------------------------------------
MCI_Stop(p_lpszDeviceID)
{
l_Return:=MCI_SendString("stop " . p_lpszDeviceID . " wait",Dummy)
return l_Return
}
;----------
;
; Function: MCI_Pause
;
;
; Description:
;
; Pauses playback or recording.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Remarks:
;
; msdn: With the MCICDA, MCISEQ, and MCIPIONR drivers, the pause command
; works the same as the stop command.
;
; Observation: For MCISEQ devices, pause works OK for me.
;
;------------------------------------------------------------------------------
MCI_Pause(p_lpszDeviceID)
{
l_Return:=MCI_SendString("pause " . p_lpszDeviceID . " wait",Dummy)
return l_Return
}
;----------
;
; Function: MCI_Resume
;
;
; Description:
;
; Resumes playback or recording after the device has been paused (see the
; MCI_Pause function).
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Remarks:
;
; msdn: Digital-video, VCR, and waveform-audio devices recognize this
; command. Although CD audio, MIDI sequencer, and videodisc devices
; also recognize this command, the MCICDA, MCISEQ, and MCIPIONR device
; drivers do not support it.
;
;
; Programming notes:
;
; An alternative to this command is the MCI_Play command. Many devices
; will begin to play where they were last paused. If the device does not
; begin playback correctly, try specifying an appropriate "From"
; and "To" value (if needed) in the p_Flags parameter.
;
;------------------------------------------------------------------------------
MCI_Resume(p_lpszDeviceID)
{
l_Return:=MCI_SendString("resume " . p_lpszDeviceID . " wait",Dummy)
return l_Return
}
;----------
;
; Function: MCI_Record
;
;
; Description:
;
; Starts recording.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Flags - Flags that determine how the device operates for
; recording. [Optional] If blank, no flags are used.
;
; Some commonly used flags include the following:
;
; from {position}
; to {position}
; insert
; overwrite
;
; If more than one flag is used, separate each flag/flag value with a
; space. For example:
;
; overwrite from 18122 to 26427
;
;
; Notes
; -----
; - The "wait" flag is not recommended. The entire application will
; be non-responsive until recording is stopped with a Stop or
; Pause command.
;
; - For a complete list of flags and descriptions for the "record"
; command string, see the "MCI Reference Guide" (link at the top
; of this library).
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Remarks:
;
; msdn: Recording stops when a Stop or Pause command is issued. For the
; MCIWAVE driver, all data recorded after a file is opened is discarded if
; the file is closed without saving it.
;
;
; Credit:
;
; Original function and examples by heresy.
;
;------------------------------------------------------------------------------
MCI_Record(p_lpszDeviceID,p_Flags="")
{
l_CmdString=record %p_lpszDeviceID% %p_Flags%
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_Return
}
;----------
;
; Function: MCI_Save
;
;
; Description:
;
; Saves an MCI file.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_FileName - File name to store a MCI file. [Required] If the file
; does not exist, a new file will be created. If the file exists, it
; will be overwritten.
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Remarks:
;
; This command can overwrite existing files. Use with care.
;
;
; Credit:
;
; Original function and examples by heresy.
;
;------------------------------------------------------------------------------
MCI_Save(p_lpszDeviceID,p_FileName)
{
l_CmdString=save %p_lpszDeviceID% "%p_FileName%"
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_Return
}
;----------
;
; Function: MCI_Seek
;
;
; Description:
;
; Move to a specified position.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Position - Position to stop the seek. [Required] Value must be
; "start", "end", or an integer.
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;------------------------------------------------------------------------------
/*
Usage and Programming notes:
MCI Bug?: For some reason, seek for cdaudio doesn't work correctly on the
first attempt. Second and susequent attempts work fine.
*/
MCI_Seek(p_lpszDeviceID,p_Position)
{
;-- Get current status
l_Status:=MCI_Status(p_lpszDeviceID)
;-- Adjust p_Position if necessary
if p_Position not in start,end
{
if p_Position is not Number
p_Position=0
p_Position:=Round(p_Position) ;-- Integer values only
if (p_Position>MCI_Length(p_lpszDeviceID))
p_Position:="end"
else
if p_Position<1
p_Position:="start"
;-- This is necessary because some devices don't like a "0"
; position.
}
;-- Seek
l_CmdString=seek %p_lpszDeviceID% to %p_Position% wait
l_Return:=MCI_SendString(l_CmdString,Dummy)
;-- Return to mode before seek
if l_Status in paused,playing
{
MCI_Play(p_lpszDeviceID)
;-- Re-pause
if l_Status=paused
MCI_Pause(p_lpszDeviceID)
}
l_CurrentPos:=MCI_Position(p_lpszDeviceID)
;-- Return to sender
return l_Return
}
;----------
;
; Function: MCI_Length
;
;
; Description:
;
; Returns the total length of the media in the current time format.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Track - Track number. [Optional] The default is 0 (no track number).
;
;
; Return value:
;
; If a track number is not specified (the default), the length of the
; entire media is returned. If a track number is specified, only the
; the length of the specified track is returned.
;
;------------------------------------------------------------------------------
MCI_Length(p_lpszDeviceID,p_Track=0)
{
;-- Build command string
l_CmdString:="status " . p_lpszDeviceID . " length"
if p_Track
l_CmdString:=l_CmdString . " track " . p_Track
;-- Send it!
MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
;----------
;
; Function: MCI_Status
;
;
; Description:
;
; Identifies the current mode of the device.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the current mode of the device.
;
; msdn: All devices can return the "not ready", "paused", "playing", and
; "stopped" values. Some devices can return the additional "open",
; "parked", "recording", and "seeking" values.
;
;------------------------------------------------------------------------------
MCI_Status(p_lpszDeviceID)
{
MCI_SendString("status " . p_lpszDeviceID . " mode",l_lpszReturnString)
return l_lpszReturnString
}
;----------
;
; Function: MCI_Position
;
;
; Description:
;
; Identifies the current playback or recording position.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Track - Track number. [Optional] The default is 0 (no track number).
;
;
; Return value:
;
; Returns the current playback or recording position in the current time
; format. If the p_Track parameter contains a non-zero value, returns the
; start position of the track relative to entire media.
;
;------------------------------------------------------------------------------
MCI_Position(p_lpszDeviceID,p_Track=0)
{
;-- Build command string
l_CmdString:="status " . p_lpszDeviceID . " position"
if p_Track
l_CmdString:=l_CmdString . " track " . p_Track
;-- Send it!
MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
;----------
;
; Function: MCI_DeviceType
;
;
; Description:
;
; Identifies the device type name.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns a device type name, which can be one of the following:
;
; cdaudio
; dat
; digitalvideo
; other
; overlay
; scanner
; sequencer
; vcr
; videodisc
; waveaudio
;
;------------------------------------------------------------------------------
MCI_DeviceType(p_lpszDeviceID)
{
l_CmdString=capability %p_lpszDeviceID% device type
MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
;----------
;
; Function: MCI_MediaIsPresent
;
;
; Description:
;
; Checks to see if media is present in the device.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns TRUE if the media is inserted in the device or FALSE otherwise.
;
; msdn: Sequencer, video-overlay, digital-video, and waveform-audio
; devices (always) return TRUE.
;
;------------------------------------------------------------------------------
MCI_MediaIsPresent(p_lpszDeviceID)
{
l_CmdString=status %p_lpszDeviceID% media present
l_RC:=MCI_SendString(l_CmdString,l_lpszReturnString)
if l_RC ;-- Probably invalid command for the device
l_Return:=false
else
if (l_lpszReturnString="true")
l_Return:=true
else
l_Return:=false
return l_Return
}
;----------
;
; Function: MCI_TrackIsAudio
;
; Description:
;
; Determines if the specified track is an audio track.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Track - Track number. [Optional] The default is 1.
;
;
; Return value:
;
; Returns TRUE if the specified track is an audio track otherwise returns
; FALSE.
;
;
; Remarks:
;
; This command will only work on a device that supports multiple tracks.
;
;------------------------------------------------------------------------------
MCI_TrackIsAudio(p_lpszDeviceID,p_Track=1)
{
if p_Track is not Integer
p_Track=1
l_CmdString=status %p_lpszDeviceID% type track %p_Track%
l_RC:=MCI_SendString(l_CmdString,l_lpszReturnString)
if l_RC ;-- Probably invalid command for the device
l_Return:=false
else
if l_lpszReturnString=audio
l_Return:=true
else
l_Return:=false
return l_Return
}
;----------
;
; Function: MCI_CurrentTrack
;
;
; Description:
;
; Identifies the current track.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the current track. The MCISEQ sequencer returns 1.
;
;------------------------------------------------------------------------------
MCI_CurrentTrack(p_lpszDeviceID)
{
l_CmdString:="status " . p_lpszDeviceID . " current track"
l_Return:=MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
;----------
;
; Function: MCI_NumberOfTracks
;
;
; Description:
;
; Identifies the number of tracks on the media.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
;
; Return value:
;
; Returns the number of tracks on the media.
;
;
; Remarks:
;
; msdn: The MCISEQ and MCIWAVE devices return 1, as do most VCR devices.
; The MCIPIONR device does not support this flag.
;
;------------------------------------------------------------------------------
MCI_NumberOfTracks(p_lpszDeviceID)
{
l_CmdString:="status " . p_lpszDeviceID . " number of tracks"
l_Return:=MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
;----------
;
; Function: MCI_SetVolume
;
;
; Description:
;
; Sets the average audio volume for both audio channels. If the left and
; right volumes have been set to different values, then the ratio of
; left-to-right volume is approximately unchanged.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Factor - Volume factor [Required]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Observations:
;
; - Factor range appears to be from 0 to 1000.
; - Most MCI devices do not support this command.
;
;------------------------------------------------------------------------------
MCI_SetVolume(p_lpszDeviceID,p_Factor)
{
l_CmdString:="setaudio " . p_lpszDeviceID . " volume to " . p_Factor
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_Return
}
;----------
;
; Function: MCI_SetBass
;
;
; Description:
;
; Sets the audio low frequency level.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Factor - Bass factor [Require]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Observations:
;
; - Factor range appears to be from 0 to ?????.
; - Most MCI devices do not support this command.
;
;------------------------------------------------------------------------------
MCI_SetBass(p_lpszDeviceID,p_Factor)
{
l_CmdString:="setaudio " . p_lpszDeviceID . " bass to " . p_Factor
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_lpszReturnString
}
;----------
;
; Function: MCI_SetTreble
;
; Description:
;
; Sets the audio high-frequency level.
;
;
; Parameters:
;
; p_lpszDeviceID - Device name or alias. [Required]
;
; p_Factor - Treble factor [Required]
;
;
; Return value:
;
; Returns the return code from the MCI_SendString function which is 0
; if the command completed successfully.
;
;
; Observations:
;
; - Factor range appears to be from 0 to ?????.
; - Most MCI devices do not support this command.
;
;------------------------------------------------------------------------------
MCI_SetTreble(p_lpszDeviceID,p_Factor)
{
l_CmdString:="setaudio " . p_lpszDeviceID . " treble to " . p_Factor
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_lpszReturnString
}
;----------
;
; Function: MCI_ToMilliseconds
;
;
; Description:
;
; Converts the specified hour, minute and second into a valid milliseconds
; timestamp.
;
;
; Parameters:
;
; Hour, Min, Sec - Position to convert to milliseconds
;
;
; Return value:
;
; The specified position converted to milliseconds.
;
;------------------------------------------------------------------------------
MCI_ToMilliseconds(Hour,Min,Sec)
{
milli:=Sec*1000
milli += (Min*60)*1000
milli += (Hour*3600)*1000
return milli
}
;----------
;
; Function: MCI_ToHHMMSS
;
;
; Description:
;
; Converts the specified number of milliseconds to hh:mm:ss format.
;
;
; Parameters:
;
; p_ms - Number of milliseconds. [Required]
;
; p_MinimumSize - Minimum size. [Optional] The default is 4. This is
; the minimum size in characters (not significant digits) that you
; want returned. Unless you want a ":" character to show as the
; leading character, don't set this value to 3 or 6.
;
;
; Return value:
;
; Returns the amount of time in hh:mm:ss format with leading zero and ":"
; characters suppressed unless the length is less than p_MinimumSize.
;
; Note: If the number of hours is greater than 99, the size of hour
; ("hh") will increase as needed.
;
;
; Usage Notes:
;
; To use this function to create separate variables for the number of
; hours, minutes, and seconds, set the p_MinimumSize parameter to 8 and
; use simple SubStr commands to create these variables. For example:
;
; x:=MCI_ToHHMMSS(NumberOfMilliseconds,8)
; HH:=SubStr(x,1,2)
; MM:=SubStr(x,4,2)
; SS:=SubStr(x,6,2)
;
; To remove leading zeros from these variables, simply add 0 to the
; extracted value. For example:
;
; MM:=SubStr(x,4,2)+0
;
;
; Credit:
;
; This function is a customized version of an example that was extracted
; from the AutoHotkey documenation.
;
;------------------------------------------------------------------------------
MCI_ToHHMMSS(p_ms,p_MinimumSize=4)
{
;-- Convert p_ms to whole seconds
if p_ms is not Number
l_Seconds=0
else
if p_ms<0
l_Seconds=0
else
l_Seconds:=floor(p_ms/1000)
;-- Initialize and format
l_Time=20121212 ;-- Midnight of an arbitrary date
EnvAdd l_Time,l_Seconds,Seconds
FormatTime l_mmss,%l_Time%,mm:ss
l_FormattedTime:="0" . l_Seconds//3600 . ":" . l_mmss
;-- Allows support for more than 24 hours.
;-- Trim insignificant leading characters
loop
if StrLen(l_FormattedTime)<=p_MinimumSize
break
else
if SubStr(l_FormattedTime,1,1)="0"
StringTrimLeft l_FormattedTime,l_FormattedTime,1
else
if SubStr(l_FormattedTime,1,1)=":"
StringTrimLeft l_FormattedTime,l_FormattedTime,1
else
break
;-- Return to sender
return l_FormattedTime
}
;----------
;
; Function: MCI_SendString
;
;
; Description:
;
; This is the primary function that controls MCI operations. With the
; exception of the formatting functions, all of the functions in this
; library call this function.
;
;
; Parameters:
;
; p_lpszCommand - MCI command string. [Required]
;
; p_lpszReturnString - Variable name that receives return information.
; [Required]
;
; p_hwndCallback - Handle to a callback window if the "notify" flag was
; specified in the command string. [Optional] The default is 0
; (No callback window).
;
;
; Return value:
;
; Two values are returned:
;
; 1) The function returns zero if successful or an error number
; otherwise. See the "Debugging" section for more information.
;
; 2) If the MCI command string was a request for information, the
; variable named in the p_lpszReturnString parameter will contain the
; requested information.
;
;
; Debugging:
;
; If a non-zero value is returned from the call to the mciSendString
; function, a call to the mciGetErrorString function is made to convert
; the error number into a developer-friendly error message. All of this
; information is sent to the debugger in an easy-to-read format.
;
;------------------------------------------------------------------------------
MCI_SendString(p_lpszCommand,ByRef p_lpszReturnString,p_hwndCallback=0)
{
VarSetCapacity(p_lpszReturnString,100,0)
l_Return:=DllCall("winmm.dll\mciSendStringA"
,"str",p_lpszCommand ;-- lpszCommand
,"str",p_lpszReturnString ;-- lpszReturnString
,"uint",100 ;-- cchReturn
,"uint",p_hwndCallback ;-- hwndCallback
,"Cdecl int") ;-- Return type
if ErrorLevel
MsgBox
,262160 ;-- 262160=0 (OK button) + 16 (Error icon) + 262144 (AOT)
,%A_ThisFunc% Function Error,
(ltrim join`s
Unexpected ErrorLevel from DllCall to the
"winmm.dll\mciSendStringA"
function. ErrorLevel=%ErrorLevel% %A_Space%
`nSee the AutoHotkey documentation (Keyword: DLLCall) for more
information. %A_Space%
)
;-- Return code?
if l_Return
{
VarSetCapacity(l_MCIErrorString,1024)
DllCall("winmm\mciGetErrorStringA"
,"uint",l_Return ;-- MCI error number
,"str",l_MCIErrorString ;-- MCI error text
,"uint",1024)
;-- This is provided to help debug MCI calls
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: Unexpected return code from command string:
"%p_lpszCommand%"
`n--------- Return code=%l_Return% - %l_MCIErrorString%
)
}
return l_Return
}
|
And here is my GUI script modified from jballi:
| Code: |
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include MCI.AHK
hMedia:=MCI_Open("new","","type waveaudio")
SetTimer showRecording,350
SetTimer showRecording,Off
Recording = 0
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record/Pause
gui Add,Button, wp hp gExit, Exit (Save as .WAV)
Gui, Add, StatusBar,, Ready
gui, Show,,MCI
Return
Record:
if (Recording = 0) {
Recording = 1
status := MCI_Record(hMedia)
SetTimer showRecording,On
gosub, showRecording
} else {
Recording = 0
status := MCI_Pause(hMedia)
SetTimer showRecording,Off
SB_SetText(" Paused")
}
return
showRecording:
Step ++
if (Step = 1)
SB_SetText("Recording")
else if (Step = 2)
SB_SetText(" Recording")
else {
SB_SetText(" Recording")
Step = 0
}
return
ESC::
Exit:
GUIClose:
MCI_Stop(hMedia)
SetTimer showRecording,Off
SB_SetText(" Saving")
FileSelectFile, SavePath, S8, .wav,,*.wav
MCI_Save(hMedia,SavePath)
SB_SetText(" Saved")
SB_SetText(" Closing")
MCI_Stop(hMedia)
MCI_Close(hMedia)
ExitApp
return
|
|
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 7:21 pm Post subject: |
|
|
SoX is an open-source audio toolkit (SoX.sourceforege.net) that works from the command line. It is a flexible and powerful player and file format converter. Recording sound is fairly easy, but it apparently is not possible to pause and then resume recording.
SoX audio recording with the "stats" option is an efficient way to analyze incoming audio as it is being recorded. (See my seismometer at www.autohotkey.com/forum/viewtopic.php?t=53012 for an example.)
Here is my AHK library script:
| Code: |
;*********************
; SoX.AHK Library
; vers 0.0.1
; by FredInGA
; Forum #53673
;*********************
;SoX Docs: http://
SoX_Open(View) {
global
IfNotExist, sox.exe
{
Msgbox,4096,Whoops!, Cannot find SoX!`n`nPlease make sure SoX.exe is located in:`n`n.
ExitApp
}
Run %comspec%,,%View%,SoXpid
WinWait, cmd.exe,
return SoXpid
}
SoX_Record() {
IfWinNotActive, cmd.exe, , WinActivate, cmd.exe,
send, SoX -d test.wav{enter}
return 1
}
SoX_Stop() {
IfWinNotActive, cmd.exe, , WinActivate, cmd.exe,
send, ^c
return 0
}
SoX_Play() {
return 2
}
SoX_Begin() {
return 0
}
SoX_End() {
return 0
}
SoX_Exit() {
IfWinNotActive, cmd.exe, , WinActivate, cmd.exe,
send, ^c
WinClose, cmd.exe
return 0
}
|
And here is my GUI script:
| Code: |
; recorderSoX.AHK by fredinga
; Forum #53673
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include SoX.AHK
;open with "MIN", "MAX", "HIDE" or "" (normal size)
SoX_Open("")
SetTimer showRecording,350
SetTimer showRecording,Off
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record
gui Add,Button, wp hp gExit, Exit (Saved as .WAV)
Gui, Add, StatusBar,, Ready
gui, Show,,SoX
Return
Record:
status := SoX_Record()
SetTimer showRecording,On
gosub, showRecording
return
showRecording:
Step ++
if (Step = 1)
SB_SetText("Recording")
else if (Step = 2)
SB_SetText(" Recording")
else {
SB_SetText(" Recording")
Step = 0
}
return
ESC::
Exit:
GUIClose:
SetTimer showRecording,Off
SB_SetText(" Closing")
status := SoX_Exit()
ExitApp
return
|
|
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 7:27 pm Post subject: |
|
|
FMOD.DLL is a powerful audio API with many options. SKAN gave us a small and efficient script (www.autohotkey.com/forum/viewtopic.php?t=28117) for analyzing the sound in an audio file and it was the starting point for my AHK library script. There is a documentation file and recording example scripts in various programming languages on the FMOD home site (FMOD.sourceforege.net). You can download the three necessary DLLs from the FMOD home site listed above.
Note: I still do not have my FMOD recorder working. I am close (I think) and will post an update as soon as I get it going. The player works.
Here is the AHK library script (still quite rough):
| Code: |
;********************
; *
; FMOD Library *
; vers 0.0.1 *
; by fredinga *
; Forum #53673 *
;********************
/*
FMOD Docs:
http://
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
exinfo.numchannels = 1;
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
exinfo.defaultfrequency = 44100;
exinfo.length = exinfo.defaultfrequency * sizeof(short) * exinfo.numchannels * 5;
*/
FMOD_Init()
{
global
fMod := DllCall("LoadLibrary", Str,"FMOD.DLL")
hWnd := WinExist()
DllCall( "FMOD.DLL\_FSOUND_SetHWND@4", UInt,hWnd )
return DllCall( "FMOD.DLL\_FSOUND_Init@12", UInt,44100, UInt,32, UInt,0)
}
FMOD_OpenStream()
{
global
fStream := DllCall("FMOD.DLL\_FSOUND_SAMPLE_Alloc@24", UInt,0, UInt,3000, UInt,FSOUND_NORMAL Or FSOUND_LOOP_NORMAL, UInt,44100, UInt,0, UInt,1 )
return fStream
}
FMOD_RecordStart()
{
global
return DllCall("FMOD.DLL\_FSOUND_Stream_RecordStart@8", UInt,fStream, UInt,0 )
}
FMOD_RecordStop()
{
return DllCall( "FMOD.DLL\_FSOUND_Stream_RecordStop@4", UInt,fStream )
}
FMOD_Close()
{
return DllCall( "FMOD.DLL\_FSOUND_Stream_Close@4", UInt,fStream )
}
FMOD_OpenFile()
{
global
Flags := ( FSOUND_MPEGACCURATE := 0x20000 )
fStream := DllCall("FMOD.DLL\_FSOUND_Stream_Open@16", Str,AudioFile, UInt,Flags, UInt,0, UInt,0 )
return fStream
}
FMOD_PlayStart()
{
global
; Channel := DllCall("FMOD.DLL\_FSOUND_Stream_PlaySound@8", UInt,1 , UInt,fStream )
Channel := DllCall("FMOD.DLL\_FSOUND_Stream_Play@8", UInt,-1, UInt,fStream )
return Channel
}
FMOD_PlayPause()
{
return DllCall( "FMOD.DLL\_FSOUND_Stream_setPaused@4", UInt,fStream )
}
FMOD_PlayStop()
{
return DllCall( "FMOD.DLL\_FSOUND_Stream_Stop@4", UInt,fStream )
}
FMOD_GetTime()
{
global
return DllCall("FMOD.DLL\_FSOUND_Stream_GetTime@4", UInt,fStream )
}
FMOD_GetLength()
{
global
return DllCall("FMOD.DLL\_FSOUND_Stream_GetLength@4", UInt,fStream, UInt,1 )
}
FMOD_GetLevels()
{
global
return DllCall("FMOD.DLL\_FSOUND_GetCurrentLevels@12", UInt,Channel, FloatP,LCh, FloatP,RCh )
}
FMOD_IsPlaying()
{
global
return DllCall("FMOD.DLL\_FSOUND_IsPlaying@4", UInt,Channel )
}
FMOD_IsRecording()
{
global
DllCall( "FMOD.DLL\_FSOUND_IsRecording@4", UInt,isRec )
return isRec
}
|
And here is my GUI script (it is still not working):
| Code: |
; recdplayFMOD.AHK by fredibga
; Forum #53673
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include FMOD.AHK
FMOD_Init()
SetTimer showActive,350
SetTimer showActive,Off
Recording = 0
Playing = 0
recdplay = ""
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gOpenFile, Open File to Play
gui Add,Button, wp h25 gPlay, Play/Pause
gui Add,Button, wp hp, =============================
gui Add,Button, wp hp gRecord, Record/Pause
gui Add,Button, wp hp gExit, Exit
Gui, Add, StatusBar,, Ready
gui, Show,,FMOD
Return
OpenFile:
fileselectfile, AudioFile, 1, , select a song,(*.mp3;*.wav)
;AudioFile = %A_WinDir%\Media\tada.wav
FMOD_OpenFile()
if (AudioFile > "-")
SB_SetText("File Loaded")
return
Play:
if (Playing = 0) {
Playing = 1
status := FMOD_PlayStart()
recdplay = Play
SetTimer showActive,On
gosub, showActive
} else{
Playing = 0
status := FMOD_PlayPause()
SetTimer showActive,Off
SB_SetText("Paused")
}
return
Record:
if (Recording = 0) {
Recording = 1
status := FMOD_RecordStart()
recdplay = Record
SetTimer showActive,On
gosub, showActive
} else{
Recording = 0
status := FMOD_RecordStop()
SetTimer showActive,Off
SB_SetText("Paused")
}
return
showActive:
Step ++
if (Step = 1) {
SB_SetText(recdplay)
} else if (Step = 2)
SB_SetText(" " recdplay)
else {
SB_SetText(" " recdplay)
Step = 0
}
return
ESC::
Exit:
GUIClose:
SetTimer showActive,Off
SB_SetText("Closing")
FMOD_RecordStop()
FMOD_PlayStop()
FMOD_Close()
ExitApp
return
|
|
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Sat Jan 23, 2010 7:33 pm Post subject: |
|
|
BASS.DLL is a massive and flexible API. k3ph wrote a very complete and professional AHK library (www.autohotkey.com/forum/viewtopic.php?t=37092) that I am using. There is a documentation file and recording example scripts in various programming languages on the BASS home site (bass.eat.at) and you can download the necessary DLLs there.
(Note: BASSMOD is a subset of BASS that does not include recording cababilities.)
My BASS recorder streams the Mic input to a simple audio level meter. I haven't yet figured out how to save that stream to a file, though.
Get the AHK library script from k3ph at his URL listed above.
And here is my GUI script (still not working):
| Code: |
; recordBASS.AHK by fredinga
; Forum #53673
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include BASS.AHK
BASS_Load()
BASS_Init(-1,44100,0,0,0)
SetTimer showActive,1000
SetTimer showActive,Off
klevel := 10000000*2.5
Recording = 0
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record/Pause
gui Add,Button, wp h25 gExit, Exit (No Save Yet)
Gui, Add, StatusBar,, Ready
gui, Show,,BASS
Return
Record:
if (Recording = 0) {
Recording = 1
status := BASS_RecordInit(-1)
hStream := BASS_RecordStart(44100,2,0,0,0)
recdplay = Record
SetTimer showActive,On
gosub, showActive
} else{
Recording = 0
status := BASS_ChannelPause(hStream)
SetTimer showActive,Off
SB_SetText("Paused")
}
return
showActive:
channellevel := BASS_ChannelGetLevel( hStream )
if (channellevel = "-1")
level2progress = 0
level := abs(channellevel) / klevel
SB_SetText("Audio Level: " level)
return
ESC::
Exit:
GUIClose:
SetTimer showActive,Off
SB_SetText("Closing")
status := BASS_ChannelStop(hStream)
BASS_Free()
ExitApp
return
|
|
|
| Back to top |
|
 |
Zaelia
Joined: 31 Oct 2008 Posts: 604 Location: France
|
Posted: Thu Jan 28, 2010 5:17 pm Post subject: |
|
|
I encourage you, it's very interesting !
cheer
Sound it's difficult, for example I work for to use WaveOutOpen for play multiple wave with embedded ressource, it's hard  |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Thu Jan 28, 2010 11:08 pm Post subject: |
|
|
Very cool stuff... I keep my Karaoke songs on my thumb drive and I've wanted to write an AHK script that can record from the system sound that I just run right from my drive, this might let me do that if I can ever find time!!!
Nice work dude!!! |
|
| Back to top |
|
 |
garry
Joined: 19 Apr 2005 Posts: 2212 Location: switzerland
|
Posted: Fri Jan 29, 2010 8:31 pm Post subject: |
|
|
thank you very much fredinga
some examples to record what you hear
streamripper records internet radio
Last edited by garry on Mon Feb 08, 2010 5:48 pm; edited 2 times in total |
|
| Back to top |
|
 |
evl
Joined: 24 Aug 2005 Posts: 1237
|
Posted: Sat Jan 30, 2010 11:21 am Post subject: |
|
|
Microphone recording: HarddiskOgg : http://www.fridgesoft.de/harddiskogg.php
Volume normalizing: mp3gain : http://mp3gain.sourceforge.net/
A while back I needed to record from a microphone. I found HarddiskOgg (records mp3, etc too). The command line mode works fine for my purpose although I always hoped for something a bit more powerful (without too many coding headaches). I then used mp3gain to normalize the volume level (i.e. boost the volume) by command line too. |
|
| Back to top |
|
 |
fredinga
Joined: 26 Jul 2009 Posts: 27 Location: Georgia, USA
|
Posted: Mon Feb 08, 2010 3:17 pm Post subject: New info |
|
|
Thanks zaelia and randallf. I appreciate your feedback.
garry had some great suggestions:
I haven't downloaded MIXMP3 yet, but will give it a try soon.
MP3DirectCut has both a command line usage and a GUI. It looks like it will be easy to construct a library of AHK functions for it. I will work on it. Nice that it is also FREE.
StreamRipper has potential as a command-line recorder for me. It appears to be similar to SoX in the way it records, but I need to explore that more.
No23 appears to be based on the BASS.DLL. It is all in German so I am still working on my translations. One limit (I think) is that it doesn't allow editing during recording sessions.
Thanks, garry, for some great links.
I downloaded harddiskogg as evl suggested. It has some interesting normalization tools while recording. It also has a command line mode that allows pause and resume while recording.
I thank you all for your audio reording tool suggestions. Very helpful! |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|