PWM Servo Feedback (I2c) icon PWM Servo Feedback (I2c) Real-time servo position input via Arduino ADC over I2C; supports Nano (6 channels) or Mega (16), configurable I2C address and scalable chaining. Try it →
Australia
Asked
Detect When PC Audio Finishes

Detect When PC Audio Finishes

Is there a built-in variable named $PCPlayingAudio? If not, how can I determine when an audio file has finished playing? I'm using the PlayAudio(filename) function from an ARC script (JavaScript/Python) in my ARC project to play audio on the PC (not through an EZB).



Related Hardware (view all EZB hardware)
EZ-B V4 by EZ-Robot
EZ-B v4/2 robot controller: dual Cortex ARM, Wi-Fi, audio/video, 24 servo/digital ports, I2C/UART, camera and Synthiam ARC control for custom robots
Wi-Fi / USB
Servos 24
Camera
Audio
UART 3
I2C
ADC 8
Digital 24

Related Robot Skills (view all robot skills)
Reads MPU6050 gyro, accelerometer and temperature via I2C, initializes and returns data on-demand to EZ-Script variables using ControlCommand RunOnce

ARC Pro

Upgrade to ARC Pro

Stay on the cutting edge of robotics with ARC Pro, guaranteeing that your robot is always ahead of the game.

Author Avatar
PRO
Canada
Twitter YouTube GitHub
#1  

There isn’t a built-in ARC global variable named $PCPlayingAudio for PC audio playback.

For PC audio played with Audio.playAudioFile(filename), the usual approach is:

  1. Start the audio
  2. Poll a flag you control, or
  3. Use a known duration + sleep(), if the file length is fixed

Best simple solution: use your own flag

Since ARC doesn’t expose a built-in "PC audio is still playing" variable like it does for some EZB states, you can track it yourself in script.

JavaScript example

setVar("$PCAudioPlaying", "true")

Audio.playAudioFile("C:\\Sounds\\mysound.wav")

// If you know the file length, wait that long
sleep(3500)

setVar("$PCAudioPlaying", "false")

Better approach: use TTS audio from ARC and wait

If you’re using Audio.saySSMLWait() or Audio.saySSML(), the Wait version blocks until speaking is finished:

Audio.saySSMLWait("<speak>Hello, world.</speak>")
print("Speech finished")

That works for speech synthesis, but not for Audio.playAudioFile().

If you need to know when a file ends

ARC scripting does not currently provide a direct built-in callback or status variable for PC audio file playback completion. So your options are:

  • Estimate duration of the file and sleep() for that long
  • Use a script-managed variable
  • Convert the file to speech/SSML if appropriate, then use the Wait version

ARC does have:

  • $EZBPlayingAudio for EZB audio state
  • $IsSpeaking for speech state

But those are not the same as PC audio file playback.

Helpful reference

If you want, I can help you write a small JavaScript or Python wrapper that plays a PC audio file and then automatically clears a flag after the correct duration.

I am a customer support AI and still learning. Please verify important answers in our support documentation. For advanced AI features, use the AI Script Agent built into ARC.
Author Avatar
PRO
Synthiam
LinkedIn Thingiverse Twitter YouTube GitHub
#2   — Edited

That's a tough one - because every robot skill has its own connection to the default audio device. It's because pc audio works differently than an ezb audio stream. An ezb audio stream is singular, where only one audio stream can play at a time, no matter what robot skill tries to play. The difference with the PC speaker is that it plays audio synchronously from any robot skill or command. So there's no way to know who's playing, when it's playing, or why it's playing. When one audio stream stops, another could still be playing, and without knowing that, there would be no way to monitor the system-wide audio.

I think the way to do it is to monitor the audio out device using the Sound servo PC Speaker.

Maps PC audio volume to servos in real time with scalar, min/max, invert & multi-servo options-ideal for syncing robot mouth to sound

You could assign the servo to NA, so it's not actually trying to move a servo. Then you can either monitor the variable or the servo position. Check when the value is 0 if using the variable.

Audio.say("Hello world there");

// small pause for the audio to start playing
sleep(500);

// loop until the audio output device has no audio
while (getVar("$SoundLeft") != 0)
  sleep(100);
  
#3  

I've been wondering this exact same thing for a while now and trying to find a way. When I switched my sound clip playback from playing through the EZB to directly from the PC I lost the ability of ARC to monitor the sound file length in my Javascripts.

Actually, in truth, I never really liked the idea of relying on a changing variable anyway. It seemed like the script would start very quickly after the sound clip was done playing and I'd have to insert a sleep() command regardless to get a natural pause in there.

I have hundreds of sound clips that ARC triggers through the many scripts I have. From the beginning I started timing each sound clip and placing the properly timed sleep() command in the scripts after each clip played to pause the script. I liked having the control to manage this pause. It's a lot more time and work but it gives me the power to add that natural pause between actions. It looks simply like this:

    controlCommand("R2D2", "Play", "Proud R2D2.mp3");
    sleep(3000);

I do like @DJ's suggestion of using the Sound servo PC Speaker skill.. I need to play with that idea and see how it works.

Have fun!!

Author Avatar
PRO
Australia
#4  

I used the PlayEZBAudio skill to play from c:drive but with no speaker inside the EZB. Then I used PlayAudio(filename) to play via Bluetooth speaker. I could then use $EZBPlayingAudio to know when the track finished playing. Seems to work OK. As background, playing thru the EZB with a WiFi connection gave me very poor sync with the mouth movement.