Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Seismograph Script Kludge (MCI and FMOD)


  • Please log in to reply
4 replies to this topic
fredinga
  • Members
  • 32 posts
  • Last active: Dec 07 2011 05:08 PM
  • Joined: 26 Jul 2009
I am working on a project to be put on the <!-- w -->www.instructables.com<!-- w --> site. My instructable will describe how to make a two-axis, mass-driven, moving-coil seismometer. (I more-or-less took a cheap stereo pair of unamplified speakers, glued fishing sinkers to each one, sealed each speaker in a plastic bubble and put them in a gallon container filled with sand.)

The seismometer plugs into the microphone input jack of the computer and that is where I could use some help. I need event detecting and recording software (written in AHK of course).

What I have so far is a combination of the MCI audio recording script written by jballi (Forum #35266) and the FMOD sound analysis program written by SKAN (Forum #28117). This kludge works well enough to get the idea across, but it has many obvious shortcomings. For example, half the time it is analyzing data and so it is not "listening" for input from the seismometer.

; SEISMOMF.AHK Forum #53012 by fredinga
;==================================================
; Autoexecute
;==================================================

#SingleInstance Force
SetWorkingDir, %A_ScriptDir%
#NoEnv

SetBatchLines -1
Process,Priority,, High

IfNotExist, fmod.dll
{
	msgbox, fmod.dll is missing
	gosub, exit
}

gosub, READINI

gui Margin,0,0
gui -MinimizeBox
if (progressYN = "Y")
	gui Add, Progress, -Smooth +0x8 hwndhwnd
Gui, Add, StatusBar, w200, Started
gui, Show, w200, Seismograph

gosub, Tic

;==================================================
; Subroutines
;==================================================

;Forum #35266 by jballi
;==================================================
Tic:
SB_SetText("TIC ==== Record")
FileDelete, loop.wav
nowUTC = %A_NowUTC%

hMedia:=MCI_Open("new","","type waveaudio")
MCI_Record(hMedia)

if (progressYN = "Y") {
SetTimer, CheckStatus,350
gosub, CheckStatus
}

sleep, msCycle

SetTimer, CheckStatus, Off
MCI_Stop(hMedia)
MCI_Save(hMedia,"loop.wav")
MCI_Close(hMedia)

gosub, Toc

return

;==================================================
CheckStatus:
Status:=MCI_Status(hMedia)
if (Status=LastStatus)
    return

if Status in playing,recording
    SendMessage, 0x40A,1,50,,ahk_id %hwnd%
 else
    SendMessage, 0x40A,0,0,,ahk_id %hwnd%

LastStatus:=Status
return

;Forum #28117 by SKAN
;==================================================
Toc:
SB_SetText("TOC ============= Analyze")
AudioData :=
doSave = 0

fMod := DllCall("LoadLibrary", Str,"FMOD.DLL")

Gui +LastFound
hWnd := WinExist()
DllCall( "FMOD.DLL\_FSOUND_SetHWND@4", UInt,hWnd )
DllCall( "FMOD.DLL\_FSOUND_Init@12", UInt,44100, UInt,32, UInt,( FSOUND_INIT_GLOBALFOCUS := 0x2))
Flags := ( FSOUND_MPEGACCURATE := 0x20000 )
fStream := DllCall("FMOD.DLL\_FSOUND_Stream_Open@16", Str,"loop.wav", UInt,Flags, UInt,0, UInt,0 )
Channel := DllCall("FMOD.DLL\_FSOUND_Stream_Play@8", UInt,-1, UInt, fStream )

Loop {
       ms := DllCall("FMOD.DLL\_FSOUND_Stream_GetTime@4", UInt,fStream )
       DllCall( "FMOD.DLL\_FSOUND_GetCurrentLevels@12", UInt,Channel, FloatP,LCh, FloatP,RCh )

	if (progressYN = "Y")
		Tooltip,% "Ms:`t" ms "`nLt:`t" lCh "`nRt:`t" rCh, % A_ScreenWidth-125,% A_ScreenHeight-125

	if (lCh > triggerLevel) {
      	AudioData .= ms "," lCh "," rCh "`n"
		doSave = 1
	}


       Sleep 1       
       If ! DllCall( "FMOD.DLL\_FSOUND_IsPlaying@4", UInt,Channel )
         Break
     } 

DllCall( "FMOD.DLL\_FSOUND_Stream_Stop@4", UInt,fStream )
DllCall( "FMOD.DLL\_FSOUND_Stream_Close@4", UInt,fStream )

if (doSave > 0) {
	FileAppend, %AudioData%, %nowUTC%.dat
	if (WAVkeepYN = "Y")
		FileCopy, loop.wav, %nowUTC%.wav
}

gosub, Tic

return

;==================================================
READINI:
	IfNotExist,%A_ScriptDir%\seismoMF.ini
		{
			ini=[Settings]
			ini=%ini%`n  progressYN = Y
			ini=%ini%`n  WAVkeepYN = Y
			ini=%ini%`n  msCycle = 10000
			ini=%ini%`n  triggerLevel = 0.048
			ini=%ini%`n
			FileAppend,%ini%,%A_ScriptDir%\seismoMF.ini
			ini=
		}
	IniRead,progressYN,%A_ScriptDir%\seismoMF.ini,Settings,progressYN
	IniRead,WAVkeepYN,%A_ScriptDir%\seismoMF.ini,Settings,WAVkeepYN
	IniRead,msCycle,%A_ScriptDir%\seismoMF.ini,Settings,msCycle
	IniRead,triggerLevel,%A_ScriptDir%\seismoMF.ini,Settings,triggerLevel
Return

;==================================================
exit:
F12::
GuiClose:
DllCall( "FMOD.DLL\_FSOUND_Stream_Stop@4", UInt,fStream )
DllCall( "FMOD.DLL\_FSOUND_Stream_Close@4", UInt,fStream )

MCI_Stop(hMedia)
MCI_Close(hMedia)
ExitApp
return

;==================================================
; Includes
;==================================================

#include MCI.ahk


(Note: Any microphone or unamplified speaker(s) plugged into the mic jack on your sound card will work with this script for demo purposes.) You will need FMOD.DLL (159 KiB) and MCI.AHK (44 KiB)along with SEISMOMF.AHK (4 KiB). I run the script from a flash drive so there aren't constant hits on the HDD.

What I want to do is either get a microphone input stream within SKAN's FMOD audio-level script (Note 1) or find a way to determine audio levels in jballi's MCI recorder (Note 2) or stream the output of the MCI recorder to the FMOD analyzer (Note 3). Help with any of these approaches would be very welcome.



Note 1: I have tried to use the recording examples in the FMOD docs to stream data to SKAN's script. But (so far) I can't make the transition from the C++ or VBasic examples to Skan's cool AHK script.

Note 2: I have gone to the Microsoft MCI docs referenced by jballi. I don't find any level-measuring functions listed that might help with this project.

Note 3: The recorded stream is held in the "hMedia" string in the MCI recorder, but this doesn't appear to be formatted in a way that the FMOD analyzer can digest directly.

  • Guests
  • Last active:
  • Joined: --
how about using bassmod, instead of fmod?

fredinga
  • Members
  • 32 posts
  • Last active: Dec 07 2011 05:08 PM
  • Joined: 26 Jul 2009
Thanks for the suggestion. I had looked at BASS earlier, but did not find any AHK recording examples. I will do some more searching on the BASS site. (Forum #15487 is another BASS reference.)

I appreciate your input.

fredinga
  • Members
  • 32 posts
  • Last active: Dec 07 2011 05:08 PM
  • Joined: 26 Jul 2009
Here is another script that I have been using to monitor the seismometer. It uses the SoX API that runs from a command line. You can download the three SoX DLLs you need from http:\\sox.sourceforge.net.
;Seismo.AHK
;ver 0.0.2 by fredinga Forum #53012

#InstallKeybdHook
SetTitleMatchMode,2
#Persistent
#SingleInstance FORCE
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
CoordMode Pixel, Screen  ; Interprets the coordinates below as relative to the screen rather than the active window.
DetectHiddenWindows, on

;;###############################################################################################
;; Defaults
;;###############################################################################################

GoSub, READINI

gHGT := HGT + 50
nowFile = ""

;;###############################################################################################
;; Autoexecute
;;###############################################################################################

nowTime = %A_NowUTC%
if (logYN = "Y")
	FileAppend, `nStart: %nowTime% Trigger: %triggerLevel%`n, log.txt

Run, %comspec%,,%view%,
WinWait, cmd.exe, 
;WinSet, Transparent, 0, cmd.exe
;WinMove, cmd.exe,,80,0,780,60,

ssi := snapIvlMin * 60000
SetTimer, doIt, %ssi%

gosub, doIt

Return 

;;###############################################################################################
;; End of autoexecute. Subroutines follow.
;;###############################################################################################

;==================================================
doIt:

IfWinNotActive, cmd.exe, , WinActivate, cmd.exe, 
send, ^c

sleep, 500

Loop, read, %seismoPath%\%nowTime%.txt
{
	look := substr(A_LoopReadLine,2,2)
	if (look = "ax")
		outLine = %A_LoopReadLine%
}

bothLevels := subStr(outLine,13,8) * 1.0
StringRight, theLevels, outLine, 20

if (bothLevels < triggerLevel) {
	FileDelete,%seismoPath%\%nowTime%.ogg
	FileDelete,%seismoPath%\%nowTime%.txt
	trig =
} else
	trig = *

if (logYN = "Y")
	FileAppend, %minsec% - %theLevels% %trig%`n, log.txt

nowTime = %A_NowUTC%
minsec := subStr(nowTime,9,6)

IfWinNotActive, cmd.exe, , WinActivate, cmd.exe, 
WinWait, cmd.exe, 
send, LIB\sox -d %seismoPath%\%nowTime%.ogg stats 2> %seismoPath%\%nowTime%.txt{enter}

return

;;#############################################################################################
;; Opening and Closing
;;#############################################################################################

;==================================================
READINI:
	IfNotExist,%A_ScriptDir%\Seismo.ini
		{
			ini=[Settings]
			ini=%ini%`n  view = MIN
			ini=%ini%`n  logYN = Y
			ini=%ini%`n  triggerLevel = 0.055
			ini=%ini%`n  snapIvlMin=5
			ini=%ini%`n  seismoPath=SEISMODATA
			ini=%ini%`n
			FileAppend,%ini%,%A_ScriptDir%\Seismo.ini
			ini=
		}
	IniRead,seismoPath,%A_ScriptDir%\Seismo.ini,Settings,seismoPath
	IniRead,snapIvlMin,%A_ScriptDir%\Seismo.ini,Settings,snapIvlMin
	IniRead,view,%A_ScriptDir%\Seismo.ini,Settings,view
	IniRead,logYN,%A_ScriptDir%\Seismo.ini,Settings,logYN
	IniRead,triggerLevel,%A_ScriptDir%\Seismo.ini,Settings,triggerLevel

Return

;========================================================

Exit:
f12::
	IfWinNotActive, cmd.exe, , WinActivate, cmd.exe, 
	send, ^c
	WinClose, cmd.exe

	ExitApp
Return


fredinga
  • Members
  • 32 posts
  • Last active: Dec 07 2011 05:08 PM
  • Joined: 26 Jul 2009
Please see my latest seismograph script.

It is here: <!-- l --><a class="postlink-local" href="http://www.autohotkey.com/community/viewtopic.php?t=91878">viewtopic.php?t=91878</a><!-- l -->