barbossa Posted March 27, 2012 Share Posted March 27, 2012 This is a simple implementation of an ABX Test for audio files. In short, you get the same audio file encoded with different bitrates/methods/codecs to check if you can spot differences between them. I tried to find some Windows software to do this (to check how good is my hearing/new headphones), but couldn't find any, so I made one myself Features include:- support for all audio formats supported by your system ;-)- simple seek bar- (poorly) synched samplesIf you find any bugs, corrections or suggestions, please let me know.Here is the code:expandcollapse popup#Region declarations #NoTrayIcon #include <Sound.au3> #include <EditConstants.au3> #include <ButtonConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <GUIEdit.au3> #Include <GuiSlider.au3> ;options Opt("GUIOnEventMode", 1) ;state variables Dim $GUIShowing = 0 Dim $bFileAValid = False Dim $bFileBValid = False Dim $fileAPath Dim $fileBPath Dim $fileAHandle Dim $fileBHandle Dim $fileXHandle Dim $playingFile = 0 Dim $numTests = 0 Dim $testHistory[51][2];50 tests, 0 is real X, 1 is guessed X ;definitions for setup GUI Dim $GUIMain = GUICreate ("ABX test setup", 640, 140) Dim $inputFileA = GUICtrlCreateInput("File A", 20, 20, 500, Default, 0x0800) Dim $buttonOpenFileA = GUICtrlCreateButton ("Open...", 530, 20, 90, Default) Dim $inputFileB = GUICtrlCreateInput("File B", 20, 60, 500, Default, 0x0800) Dim $buttonOpenFileB = GUICtrlCreateButton ("Open...", 530, 60, 90, Default) Dim $labelFileAOK = GUICtrlCreateLabel ("File A invalid", 20, 100, 100, Default) Dim $labelFileBOK = GUICtrlCreateLabel ("File B invalid", 120, 100, 100, Default) Dim $buttonStart = GUICtrlCreateButton ("Start test", 520, 100, 100, Default) Dim $buttonAbout = GUICtrlCreateButton ("About...", 400, 100, 100, Default) GUICtrlSetOnEvent ($buttonOpenFileA, "OpenFileA") GUICtrlSetOnEvent ($buttonOpenFileB, "OpenFileB") GuiCtrlSetOnEvent ($buttonStart, "StartTest") GuiCtrlSetOnEvent ($buttonAbout, "AboutBox") GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") Dim $GUITest = GUICreate ("ABX test", 260, 300) Dim $soundPosition = GUICtrlCreateSlider(16, 112, 225, 33) Dim $buttonPlayA = GUICtrlCreateButton("Play A", 16, 32, 65, 65) Dim $buttonPlayB = GUICtrlCreateButton("Play B", 96, 32, 65, 65) Dim $buttonPlayX = GUICtrlCreateButton("Play X", 176, 32, 65, 65) Dim $labelTestNumber = GUICtrlCreateLabel("Test Number:", 16, 8, 68, 17) Dim $buttonXisA = GUICtrlCreateButton("X is A", 56, 152, 65, 65) Dim $buttonXisB = GUICtrlCreateButton("X is B", 136, 152, 65, 65) Dim $buttonStopSound = GUICtrlCreateButton("STOP SOUND", 16, 216, 225, 33) Dim $buttonEndTest = GUICtrlCreateButton("END TEST", 16, 256, 225, 33) GUICtrlSetOnEvent ($buttonPlayA, "PlayA") GUICtrlSetOnEvent ($buttonPlayB, "PlayB") GUICtrlSetOnEvent ($buttonPlayX, "PlayX") GuiCtrlSetOnEvent ($soundPosition, "SeekSound") GuiCtrlSetOnEvent ($buttonStopSound, "StopSound") GuiCtrlSetOnEvent ($buttonEndTest, "EndTests") GuiCtrlSetOnEvent ($buttonXisA, "XisA") GuiCtrlSetOnEvent ($buttonXisB, "XisB") GuiCtrlSetOnEvent ($buttonEndTest, "EndTests") GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") Dim $GUIresults = GUICreate("Test results", 330, 440) Dim $textResults = GUICtrlCreateEdit("", 8, 8, 313, 417, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY)) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") #endregion declarations #region Main Loop GUISwitch($GUIMain) GUISetState(@SW_SHOW) While True Sleep (1000) Switch $GUIShowing Case 0 If $bFileAValid Then GUICtrlSetData($labelFileAOK, "File A VALID") Else GUICtrlSetData($labelFileAOK, "File A invalid") EndIf If $bFileBValid Then GUICtrlSetData($labelFileBOK, "File B VALID") Else GUICtrlSetData($labelFileBOK, "File B invalid") EndIf Case 1 If _SoundStatus($playingFile) = "playing" Then GUICtrlSetData($soundPosition, Ceiling((_SoundPos($playingFile, 2) / _SoundLength($playingFile, 2)) * 100)) EndIf EndSwitch WEnd #endregion Main Loop #region Functions Func CLOSEClicked() MsgBox(64, "Exit", "Exiting...", 2) Exit EndFunc Func OpenFileA () $fileAPath = FileOpenDialog ("Audio file A", Default, "Audio Files (*.mp3;*.wav;*.flac)", 3) If @error <> 1 Then _GUICtrlEdit_SetText($inputFileA, $fileAPath) $fileAHandle = _SoundOpen($fileAPath) If @error <> 0 Then MsgBox(16, "Error", "Error loading the file.", 0, $GUIMain) $bFileAValid = False Else MsgBox(64, "OK", "File loaded successfully.", 0, $GUIMain) $bFileAValid = True EndIf Else MsgBox(16, "Error", "Error opening the file.", 0, $GUIMain) EndIf EndFunc Func OpenFileB () $fileBPath = FileOpenDialog ("Audio file B", Default, "Audio Files (*.mp3;*.wav;*.flac)", 3) If @error <> 1 Then _GUICtrlEdit_SetText($inputFileB, $fileBPath) $fileBHandle = _SoundOpen($fileBPath) If @error <> 0 Then MsgBox(16, "Error", "Error loading the file.", 0, $GUIMain) $bFileBValid = False Else MsgBox(64, "OK", "File loaded successfully.", 0, $GUIMain) $bFileBValid = True EndIf Else MsgBox(16, "Error", "Error opening the file.", 0, $GUIMain) EndIf EndFunc Func StartTest () If $bFileAValid And $bFileBValid Then GUISetState(@SW_HIDE) GUISwitch($GUITest) GUISetState(@SW_SHOW) $GUIShowing = 1 NewTest() Else MsgBox (16, "Error", "Both files must be valid.", 0, $GUIMain) EndIf EndFunc Func PlayA () _SoundPause($playingFile) $playingFile = $fileAHandle SeekSound () EndFunc Func PlayB () _SoundPause($playingFile) $playingFile = $fileBHandle SeekSound () EndFunc Func PlayX () _SoundPause($playingFile) $playingFile = $fileXHandle SeekSound () EndFunc Func SeekSound () Dim $hour, $minute, $second Dim $percent Dim $time_in_seconds $percent = _GUICtrlSlider_GetPos($soundPosition) $time_in_seconds = Floor((_SoundLength($playingFile, 2) / 1000) * ($percent / 100)) $hour = Floor($time_in_seconds/3600) $time_in_seconds = Mod($time_in_seconds, 3600) $minute = Floor($time_in_seconds/60) $time_in_seconds = Mod($time_in_seconds, 60) $second = $time_in_seconds _SoundSeek($playingFile, $hour, $minute, $second) _SoundPLay($playingFile) EndFunc Func StopSound () _SoundStop($playingFile) EndFunc Func XisA () $testHistory[$numTests][1] = "A" NewTest() EndFunc Func XisB () $testHistory[$numTests][1] = "B" NewTest() EndFunc Func AboutBox () MsgBox(0, "About ABX tester", _ "Implement ABX double blind test for different quality settings audio files." & @CRLF & _ "The test consists of a number of trials in wich the test subject must listen" & @CRLF & _ "to two audio samples (A and B) and compare them to one of them, randomly" & @CRLF & _ "assigned to X. For a minimum of 16 tests, if the subject chooses the correct" & @CRLF & _ "file less than 95% of the time, then the null hypothesis (there is no signi-" & @CRLF & _ "ficant difference between A and B) cannot be rejected." & @CRLF & _ "" _ , 0, $GUIMain) EndFunc Func EndTests() Dim $i Dim $totalRight = 0 Dim $tmpData GUISetState(@SW_HIDE) GUISwitch($GUIresults) GUISetState(@SW_SHOW) $GUIShowing = 2 For $i = 1 to $numTests If $testHistory[$i][1] <> "" Then $tmpData = $tmpData & "Test " & StringFormat("%02d", $i) & ": X was " & _ $testHistory[$i][0] & ", your answer was " & _ $testHistory[$i][1] & @CRLF If $testHistory[$i][0] = $testHistory[$i][1] Then $totalRight += 1 EndIf EndIf Next $tmpData = $tmpData & "Total right: " & $totalRight & " (" & Round(($totalRight/$numTests)*100, 2) & "%)" GuiCtrlSetData($textResults, $tmpData) EndFunc ;randomly assigns file A or B to X Func SetFileX () Dim $i $i = Random (1, 2, 1) If $i = 1 Then $fileXHandle = $fileAHandle $testHistory[$numTests][0] = "A" Else $fileXHandle = $fileBHandle $testHistory[$numTests][0] = "B" EndIf EndFunc Func NewTest () If $numTests < 50 Then $numTests += 1 MsgBox(64, "Setting X", "Test " & $numTests & @CRLF & "setting file X...", 2, $GUITest) SetFileX() GUICtrlSetData($labelTestNumber, $numTests) StopSound() Else EndTests() EndIf EndFunc #endregion Functions 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