static void playSound (ExperimentMFC me, Sound sound, Sound carrierBefore, Sound carrierAfter, double initialSilenceDuration, double finalSilenceDuration) { long numberOfSamplesWritten = 0; long initialSilenceSamples = lround (initialSilenceDuration / my samplePeriod); for (long channel = 1; channel <= my numberOfChannels; channel ++) { for (long i = 1; i <= initialSilenceSamples; i ++) { my playBuffer -> z [channel] [i] = 0.0; } } numberOfSamplesWritten += initialSilenceSamples; if (carrierBefore) { for (long channel = 1; channel <= my numberOfChannels; channel ++) { NUMvector_copyElements <double> (carrierBefore -> z [channel], my playBuffer -> z [channel] + numberOfSamplesWritten, 1, carrierBefore -> nx); } numberOfSamplesWritten += carrierBefore -> nx; } if (sound) { for (long channel = 1; channel <= my numberOfChannels; channel ++) { NUMvector_copyElements <double> (sound -> z [channel], my playBuffer -> z [channel] + numberOfSamplesWritten, 1, sound -> nx); } numberOfSamplesWritten += sound -> nx; } if (carrierAfter) { for (long channel = 1; channel <= my numberOfChannels; channel ++) { NUMvector_copyElements <double> (carrierAfter -> z [channel], my playBuffer -> z [channel] + numberOfSamplesWritten, 1, carrierAfter -> nx); } numberOfSamplesWritten += carrierAfter -> nx; } long finalSilenceSamples = lround (finalSilenceDuration / my samplePeriod); for (long channel = 1; channel <= my numberOfChannels; channel ++) { for (long i = 1; i <= finalSilenceSamples; i ++) { my playBuffer -> z [channel] [i + numberOfSamplesWritten] = 0.0; } } numberOfSamplesWritten += finalSilenceSamples; if (! my blankWhilePlaying) my startingTime = Melder_clock (); Sound_playPart (my playBuffer.get(), 0.0, numberOfSamplesWritten * my samplePeriod, 0, nullptr); if (my blankWhilePlaying) my startingTime = Melder_clock (); }
double Melder_stopwatch () { static double lastTime; double now = Melder_clock (); double timeElapsed = lastTime == 0 ? -1.0 : now - lastTime; //Melder_casual ("%ld %ld %ld %lf %lf", now, lastTime, now - lastTime, (now - lastTime) / (double) CLOCKS_PER_SEC, timeElapsed); lastTime = now; return timeElapsed; }
static void gui_drawingarea_cb_key (I, GuiDrawingAreaKeyEvent event) { iam (RunnerMFC); if (my graphics == NULL) return; // Could be the case in the very beginning. ExperimentMFC experiment = (ExperimentMFC) my data; if (my data == NULL) return; double reactionTime = Melder_clock () - experiment -> startingTime; if (! experiment -> blankWhilePlaying) reactionTime -= experiment -> stimulusInitialSilenceDuration; if (experiment -> trial == 0) { } else if (experiment -> pausing) { } else if (experiment -> trial <= experiment -> numberOfTrials) { long iresponse; if (experiment -> ok_key != NULL && experiment -> ok_key [0] == event -> key && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { do_ok (me); } else if (experiment -> replay_key != NULL && experiment -> replay_key [0] == event -> key && my numberOfReplays < experiment -> maximumNumberOfReplays) { do_replay (me); } else if (experiment -> oops_key != NULL && experiment -> oops_key [0] == event -> key) { if (experiment -> trial > 1) { do_oops (me); } } else if (experiment -> responses [experiment -> trial] == 0) { for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; if (response -> key != NULL && response -> key [0] == event -> key) { experiment -> responses [experiment -> trial] = iresponse; experiment -> reactionTimes [experiment -> trial] = reactionTime; if (experiment -> responsesAreSounds) { ExperimentMFC_playResponse (experiment, iresponse); } if (experiment -> ok_right <= experiment -> ok_left && experiment -> numberOfGoodnessCategories == 0) { do_ok (me); } else { my broadcastDataChanged (); Graphics_updateWs (my graphics); } } } } } }
static void gui_drawingarea_cb_click (I, GuiDrawingAreaClickEvent event) { iam (RunnerMFC); if (my graphics == NULL) return; // Could be the case in the very beginning. ExperimentMFC experiment = (ExperimentMFC) my data; if (my data == NULL) return; double reactionTime = Melder_clock () - experiment -> startingTime; if (! experiment -> blankWhilePlaying) reactionTime -= experiment -> stimulusInitialSilenceDuration; double x, y; Graphics_DCtoWC (my graphics, event -> x, event -> y, & x, & y); if (experiment -> trial == 0) { // the first click of the experiment experiment -> trial ++; my broadcastDataChanged (); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { if (experiment -> numberOfTrials < 1) { Melder_flushError ("There are zero trials in this experiment."); forget (me); return; } autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [1]); // works only if there is at least one trial } } else if (experiment -> pausing) { // a click to leave the break if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top && experiment -> trial > 1) { do_oops (me); } else { experiment -> pausing = FALSE; experiment -> trial ++; my broadcastDataChanged (); if (experiment -> blankWhilePlaying) { Graphics_setGrey (my graphics, 0.8); Graphics_fillRectangle (my graphics, 0, 1, 0, 1); Graphics_setGrey (my graphics, 0.0); Graphics_flushWs (my graphics); } Graphics_updateWs (my graphics); if (experiment -> stimuliAreSounds) { autoMelderAudioSaveMaximumAsynchronicity saveMaximumAsynchronicity; if (experiment -> blankWhilePlaying) MelderAudio_setOutputMaximumAsynchronicity (kMelder_asynchronicityLevel_SYNCHRONOUS); ExperimentMFC_playStimulus (experiment, experiment -> stimuli [experiment -> trial]); } } } else if (experiment -> trial <= experiment -> numberOfTrials) { long iresponse; if (x > experiment -> ok_left && x < experiment -> ok_right && y > experiment -> ok_bottom && y < experiment -> ok_top && experiment -> responses [experiment -> trial] != 0 && (experiment -> numberOfGoodnessCategories == 0 || experiment -> goodnesses [experiment -> trial] != 0)) { do_ok (me); } else if (x > experiment -> replay_left && x < experiment -> replay_right && y > experiment -> replay_bottom && y < experiment -> replay_top && my numberOfReplays < experiment -> maximumNumberOfReplays) { do_replay (me); } else if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top && experiment -> trial > 1) { do_oops (me); } else if (experiment -> responses [experiment -> trial] == 0 || experiment -> ok_right > experiment -> ok_left) { for (iresponse = 1; iresponse <= experiment -> numberOfDifferentResponses; iresponse ++) { ResponseMFC response = & experiment -> response [iresponse]; if (x > response -> left && x < response -> right && y > response -> bottom && y < response -> top && response -> name [0] != '\0') { experiment -> responses [experiment -> trial] = iresponse; experiment -> reactionTimes [experiment -> trial] = reactionTime; if (experiment -> responsesAreSounds) { ExperimentMFC_playResponse (experiment, iresponse); } if (experiment -> ok_right <= experiment -> ok_left && experiment -> numberOfGoodnessCategories == 0) { do_ok (me); } else { my broadcastDataChanged (); Graphics_updateWs (my graphics); } } } if (experiment -> responses [experiment -> trial] != 0 && experiment -> ok_right > experiment -> ok_left) { for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC cat = & experiment -> goodness [iresponse]; if (x > cat -> left && x < cat -> right && y > cat -> bottom && y < cat -> top) { experiment -> goodnesses [experiment -> trial] = iresponse; my broadcastDataChanged (); Graphics_updateWs (my graphics); } } } } else if (experiment -> responses [experiment -> trial] != 0) { Melder_assert (experiment -> ok_right <= experiment -> ok_left); for (iresponse = 1; iresponse <= experiment -> numberOfGoodnessCategories; iresponse ++) { GoodnessMFC cat = & experiment -> goodness [iresponse]; if (x > cat -> left && x < cat -> right && y > cat -> bottom && y < cat -> top) { experiment -> goodnesses [experiment -> trial] = iresponse; do_ok (me); } } } } else { if (x > experiment -> oops_left && x < experiment -> oops_right && y > experiment -> oops_bottom && y < experiment -> oops_top) { do_oops (me); return; } if (my iexperiment < my experiments -> size) { my iexperiment ++; if (! RunnerMFC_startExperiment (me)) { Melder_flushError (NULL); forget (me); return; } } } }