Old 05-17-2022, 12:39 PM   #1
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default Audible warning for ripple mode

Hi, I'd like to write a script to give an audible beep every 30 seconds or so if I'm in ripple all tracks mode. No beeps if ripple mode is off or I'm playing or recording. I'm blind so it can be less obvious both that ripple mode is on and also that I am doing editting that is completely messing inadvertently with my project. I might think I'm just cutting a short bit off the end of an item not knowing I'm cutting up and moving items right down the project.
Things this script will need to do that I don't really know how to do include:
Make a beep (I'll need to check status of play / record mode as well as ripple mode)
Do this every 30 seconds
Run as soon as Reaper starts
Please could people give me some guidance on how to code these 3 things?
Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-17-2022, 02:04 PM   #2
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,255
Default

I'd suggest building custom actions to turn it off when doing common things, like hitting play. This is what I've done. Basically just be cognizant of when it's getting in your way and then try to make actions that ensure it's off in those situations.

For me, it's something I generally want to use very briefly and ensure it's off most of the time (usually right after I use it, I want it off again), so I prefer simply not having to remember to do that.
__________________
foxyyymusic
foxAsteria is online now   Reply With Quote
Old 05-18-2022, 09:35 AM   #3
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi,
I agree that getting into the habit of turning off ripple mode unless you need it at the time is a good approach but I'd like to write the script for myself and others for when we forget.
Hope someone can point me to ways to write it.
Best,
Castle
Quote:
Originally Posted by foxAsteria View Post
I'd suggest building custom actions to turn it off when doing common things, like hitting play. This is what I've done. Basically just be cognizant of when it's getting in your way and then try to make actions that ensure it's off in those situations.

For me, it's something I generally want to use very briefly and ensure it's off most of the time (usually right after I use it, I want it off again), so I prefer simply not having to remember to do that.
Castle Starter is offline   Reply With Quote
Old 05-18-2022, 11:24 AM   #4
foxAsteria
Human being with feelings
 
foxAsteria's Avatar
 
Join Date: Dec 2009
Location: Oblivion
Posts: 10,255
Default

Just in case I wasn't clear, I wasn't suggesting you make new habits. What I meant was to create a custom action from some action you use a lot (e.g Play, or clicking in the arrange) and add "set ripple editing off" to it.

This way you don't have to remember, write a script or wait for a beep to remind you. You'd be turning it off automatically whenever you do some common thing. One can do a lot of damage in 30 seconds...Anyways, that's what solved the problem for me.

But again, I never need ripple to stay on for any length of time. It's something I turn on, do one edit and then want it back off immediately. If that sounds like you, it can probably work for you too.
__________________
foxyyymusic
foxAsteria is online now   Reply With Quote
Old 05-19-2022, 07:43 AM   #5
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

I'll try one, but it will need JS-extension to be installed. It can be installed via ReaPack from the ReaTeam-Extensions-repository.
Should be easy.

Do you have a beep-sound of your choice already?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-19-2022, 11:19 AM   #6
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Fox, I see. I get you now. That makes sense. I'll give that some thought. It needs to be somewhere in the region of common enough to disable ripple mode frequently and not something you would need whilst ripple mode is on.
Thanks for the suggestion.
Castle
Quote:
Originally Posted by foxAsteria View Post
Just in case I wasn't clear, I wasn't suggesting you make new habits. What I meant was to create a custom action from some action you use a lot (e.g Play, or clicking in the arrange) and add "set ripple editing off" to it.

This way you don't have to remember, write a script or wait for a beep to remind you. You'd be turning it off automatically whenever you do some common thing. One can do a lot of damage in 30 seconds...Anyways, that's what solved the problem for me.

But again, I never need ripple to stay on for any length of time. It's something I turn on, do one edit and then want it back off immediately. If that sounds like you, it can probably work for you too.
Castle Starter is offline   Reply With Quote
Old 05-19-2022, 11:27 AM   #7
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi, for a beep sound I was just thinking of a short beep like you hear when astronauts are talking to indicate they have stopped talking. Just a 1000Hz sine wave I guess.

It would be great if you could prototype something. thank you.

I just looked in reaPack and typed "extension" and closest looking thing was reaScript API by Julian Sader. But that doesn't sound like th the one you meant. How do I query the reaTeam repository?
Many thanks,
Castle
Quote:
Originally Posted by Meo-Ada Mespotine View Post
I'll try one, but it will need JS-extension to be installed. It can be installed via ReaPack from the ReaTeam-Extensions-repository.
Should be easy.

Do you have a beep-sound of your choice already?
Castle Starter is offline   Reply With Quote
Old 05-20-2022, 07:19 AM   #8
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by Castle Starter View Post
Hi, for a beep sound I was just thinking of a short beep like you hear when astronauts are talking to indicate they have stopped talking. Just a 1000Hz sine wave I guess.

It would be great if you could prototype something. thank you.

I just looked in reaPack and typed "extension" and closest looking thing was reaScript API by Julian Sader. But that doesn't sound like th the one you meant. How do I query the reaTeam repository?
Many thanks,
Castle
Yup, that's the one, ReaScript API. Just install it as I need this to play the sound.

Maybe I can give you the actual astronaut beep for this...

Ripple One is not important for you? Otherwise I can add both with different sounds to distinguish them.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-20-2022, 01:57 PM   #9
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Meo,
Here are two beep files. A double beep for all tracks ripple mode:
https://www.dropbox.com/s/a6s3t4atqe...lBeep.wav?dl=0

And a single beep for track ripple mode:
https://www.dropbox.com/s/cndb22s5j4...kBeep.wav?dl=0

They are the 2500Hz and 2475Hz beeps used in Apollo11 but with the edges smoothed off to avoid clicks.

Will you be able to simply paste the script text to this thread?

Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-21-2022, 07:47 AM   #10
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Yup. I've finished one today but want to give it some more days for final testing. When it's done, I post the code here with comments and everything.
If everything works out, you'll also be able to make modified versions of it, so you can get audio-warnings for other things as well.

Thnx for the audios. Will test the code with it as well
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-23-2022, 04:54 AM   #11
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Ok, this is my attempt of doing it. Just create a new script and copy and paste this code into the new script.
You need to set the filename+path of the ping-sound of your choice in line 10.
You can also alter some other behavior, like, how often shall the sound be played, how loud it shall be, which output-channel of your sound-device to use and a delay, for when you don't want to have the ping-sound starting immediately but rather some seconds later.

You can also alter the code to warn you acoustically of other things as well. Just make a new script with it, change the filename and path of the ping-sound to a different one AND alter the code in the GetCurrentState-function to return true, if a ping-sound shall be played or false, if not.
This way, you'll be able to make various state-warn-scripts if you need more for different usecases and contexts.

Oh, and if you want to hear the warning sound only once and not be repeated, set seconds_between_each_ping in line 11 to 0.
This could be helpful in some cases, where you only want to be warned once when the state appears that you want to be warned about but not repeatedly.

After some of the points FoxAsteria made, I also added, that you can set the sound to looped (set seconds_between_each_ping in line 11 to the value -1).
That way, you can have a looped sound playing for as long as you have ripple all=on and play/rec=off.
So you can create a "soundscape" running for the time you want to be warned so you immediately recognize and not after x seconds.
It will be stopped as soon as play/rec=on or ripple all=off.

I also added dozens of comments to the code, so if you want to toy around with it, you have some explanations to it(I hope I didn't overdo it )

Please test the code some time before using it productive. Some functions might crash Reaper, if I messed up the code, so if you experience a crash while testing, hit me up and I improve it(it's possible to make it non-crashing).
Though I think, I catched all these cases but I want to be sure that you don't loose work just because I missed one edge-case in my code.

Feel free to ask questions, if something isn't clear or too complicated, we'll figure this out.

So without much further ado, here's the code:

Code:
-- Play Ping Sound every x seconds, when Ripple-All=on and Play/Rec=off
-- Meo-Ada Mespotine - 21st of May 2022 - licensed under MIT-license

-- You can modify this script to check for other states as well. For this, make a copy of this script and alter the GetCurrenState-function, so it returns true, when you want to hear the sound or false, if you don't want to.
-- The rest of the code you probably don't need to touch or look at, but I added comments in case you are curious.
-- You can set various values in the next few lines to customize, how often you want the playsound to be played, its volume
-- where the file can be found and a delay for the first time the sound is played.

-- You can change these variables to the values you prefer:
  ping_sound_filename=reaper.GetResourcePath().."/Scripts/1.mp3" -- the path and filename of the ping-sound
  seconds_between_each_ping=30 -- the number of seconds to wait inbetween each ping; 
                               -- 0, to play the sound only once and -1 to start the sound immediately and loop it until ripple=off and/or play/rec=true
  ping_volume=1         -- the volume of the ping-sound; 0 for off; 10 is maximum
  ping_output_channel=0 -- the hardware-output-channel of your device, that shall play the ping sound(0 for default)
  ping_delay=0      -- the number of seconds to wait, until the sound is played for the first time(0 to start playing immediately after ripple edit=on and play/rec=off)
                    -- with this, you can avoid being annoyed immediately by the sound, when you realised yourselves, that you accidentally had ripple-all on so you have 
                    -- time to turn it off before the first ping reminds you

function GetCurrentState()
  -- This is the function you need to alter, if you want to check for something else than ripple-all and play/rec.
  -- Just get the state and return true if you want to play the sound or return false, if not.
  -- The wait-time-between two pings will be done in the rest of the code outside this function, so you don't 
  -- need to bother with that. Just return true for as long as you want to have a sound played and the rest should work automatically.
  
  local state=reaper.GetToggleCommandState(41991) -- check, if ripple-all-state is on(1) or off(0)
  if reaper.GetPlayState()~=0 then state=0 end -- If you play/record currently, ignore the ripple-all-state by setting state=0. 

  if state==1 then return true else return false end
end


-- You probably don't need to look at the rest of the code from here on

function main()
  -- let's get, if the sound shall be played(true) or not(false)
  local cur_state=GetCurrentState()
  
  -- Now we go to the counting of time and playing the sound-logic. 

  -- Some notes on how the number of seconds between each ping is calculated:
  -- Reaper executes this script approximately 33 times per second, so we need to have a counter-variable valled counter,
  -- to check, whether one second is gone(script was executed 33 times).
  -- We will use this variable in various ways. 
  -- For instance, everytime, the counter-variable reaches ping_delay*33, we will play the sound.
  -- To know, when to play the sound again, we check when the counter-variable is 33*seconds_between_each_ping.
  -- In that case, we will reset the value of counter to 0 to restart measuring the time again.

  -- if cur_state is true(turned on) then do the sound magic
  if cur_state==true then
    -- if the counter reaches the delay-value in seconds (delay*33) then play the sound once
    if seconds_between_each_ping~=-1 and counter==math.floor(ping_delay*33) then
      reaper.Xen_StopSourcePreview(-1)
      local PCM_Source=reaper.PCM_Source_CreateFromFile(ping_sound_filename)
      id=reaper.Xen_StartSourcePreview(PCM_Source, ping_volume, false, ping_output_channel)
    elseif seconds_between_each_ping==-1 and started~=true then
      local PCM_Source=reaper.PCM_Source_CreateFromFile(ping_sound_filename)
      id=reaper.Xen_StartSourcePreview(PCM_Source, ping_volume, -1, ping_output_channel)
      count=-1
      started=true
    end
    counter=counter+1
  -- if cur_state is off(false), then reset the counter and wait, so no sound is played.
  elseif cur_state==false then
    counter=-1
    started=false
    reaper.Xen_StopSourcePreview(-1)
  end
  
  -- if the maximum time between two pings has been reached, reset the counter and restart counting again
  -- it waits for "33*seconds_between_each_ping" which is the number of times, Reaper executes the script in the background 
  -- in the amount of seconds between each ping
  if seconds_between_each_ping~=0 and counter>=33*seconds_between_each_ping then
    counter=0
  end
  reaper.defer(main)
end

function atexit()
  reaper.Xen_StopSourcePreview(id)
end

reaper.atexit(atexit)

-- check, if JS-extension is correctly installed
if reaper.Xen_StartSourcePreview==nil then reaper.MB("JS-extension doesn't seem to be installed...", "error", 0) return end
counter=0    -- counter-variable needed by the script; don't change.

main()
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-23-2022, 01:49 PM   #12
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Wow Meo, from a first try this is amazing. Just what I was after. Many many thanks. I've done some LUA work but nothing this complex and I doubt I would have been able to write this.

First feedback is how to stop the script running? I've set a keyboard shortcut to the script and I unintentionally hit the key twice so I ended up with a double beep. So actually, possibly two questions. If I did want to stop the script running, how to do that? And can you make it so two instances can't run?

The volume of 1 is quite loud. I put it to 4 and got a big blast. I'm not going near 10! As you are using a library function I guess there isn't much you can do to make the setting of 1 quieter? The cure then will be to use a quieter .wav file.

And just to check my understanding, this script detects ripple all so I can copy this cript and adapt it to detect ripple track and run that, and tweak with a different sound file. So that will then cover both ripple all and ripple track.

Last question - is it possible to auto-run this script on Reaper startup so the user doesn't have to remember to run it?

Actually - two more questions? I'll test it more, but after that are you happy I share this with friends in the Reapers Without Peepers community? There are others who would like this script I am sure. And can I give you a donation for your time? Do you have a PayPal account I can give to?

Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-24-2022, 06:38 AM   #13
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

I'm away from my computer so I give some quick answers.

You can set it as startup-action. There are numerous ways to do it, so it's best to ask in the General forum for this, to get some other answers as well.
If you use SWS, you can look at Startup actions, which is probably the easiest way to do it.

The volume you can set also to 0.5 0.3 or something. This way, you can make it more silent.

The multiple scripts run at the same time, I guess, Reaper showed you at some point a dialog that gave you an option to run another instance or stop instance. It sounds like you hit the "neew instance" button with the "remember setting" checkbox checked.

Easiest fix: restart Reaper and run only once the next time.
Another way(if my assumption with the dialog was correct) is to delete the script, create it new, run it twice and hit the "Terminate instance"-button in the next dialog with the "remember setting"-checkbox checked.

Yes, you can make a copy of it as new script and adapt the GetCurrentState-function to use the command id of ripple-track instead of ripple-all.
You just need to change the number in the reaper.Main_OnCommand-line and, as you said, set a different sound in this script, so you can differentiate between them.
It should also allow adapting for checking for other things as well, like locked tracks, no recarmed-tracks or loop is on, etc, in case you need it.
Just make new copy, set the sound and adapt GetCurrentState-function and it should work

Your last question, sure, feel free to share it. But test it for some time further, just to make sure, it really doesn't crash. When it remains stable with all tests, feel free to share it

Thanks for the donation

Oh, regarding two instances: you mean, two instances can run but you only hear one sound?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-26-2022, 03:07 PM   #14
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Meo,
I've come across a problem when running two versions of the script. One for ripple all and one for ripple track.
I duplicated the ripple all script file and renamed it to a suitable name for just ripple track. I changed the .wav file played and the action ID in GetCurrentState to 41990 which is the Toggle Track Ripple action.
By itself, this new script works as expected. It beeps a single beep when in ripple track mode as opposed to a double beep when in ripple all mode from the original script.
Now if I run both scripts the sound files are not played correctly I hear only a small fraction of the sound. and behaviour isn't reliable. Is there some conflict between the two scripts as they both use the same time counter or something?
Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-26-2022, 11:29 PM   #15
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

I have a look. Maybe, the feature I use for playing a sound allows only one at a time, which would be a Reaper limitation.
Maybe I can work around it(I hope)...
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-27-2022, 09:18 AM   #16
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Ok, here's the revised code. It should work now with multiple instances. Hope I got it right...

Code:
-- Play Ping Sound every x seconds, when Ripple-All=on and Play/Rec=off
-- Meo-Ada Mespotine - 27th of May 2022 - licensed under MIT-license

-- You can modify this script to check for other states as well. For this, make a copy of this script and alter the GetCurrenState-function, so it returns true, when you want to hear the sound or false, if you don't want to.
-- The rest of the code you probably don't need to touch or look at, but I added comments in case you are curious.
-- You can set various values in the next few lines to customize, how often you want the playsound to be played, its volume
-- where the file can be found and a delay for the first time the sound is played.

-- You can change these variables to the values you prefer:
  ping_sound_filename=reaper.GetResourcePath().."/Scripts/1.mp3" -- the path and filename of the ping-sound
  seconds_between_each_ping=7 -- the number of seconds to wait inbetween each ping; 
                               -- 0, to play the sound only once and -1 to start the sound immediately and loop it until ripple=off and/or play/rec=true
  ping_volume=0.5         -- the volume of the ping-sound; 0 for off; 10 is maximum
  ping_output_channel=0 -- the hardware-output-channel of your device, that shall play the ping sound(0 for default)
  ping_delay=0      -- the number of seconds to wait, until the sound is played for the first time(0 to start playing immediately after ripple edit=on and play/rec=off)
                    -- with this, you can avoid being annoyed immediately by the sound, when you realised yourselves, that you accidentally had ripple-all on so you have 
                    -- time to turn it off before the first ping reminds you

function GetCurrentState()
  -- This is the function you need to alter, if you want to check for something else than ripple-all and play/rec.
  -- Just get the state and return true if you want to play the sound or return false, if not.
  -- The wait-time-between two pings will be done in the rest of the code outside this function, so you don't 
  -- need to bother with that. Just return true for as long as you want to have a sound played and the rest should work automatically.
  
  local state=reaper.GetToggleCommandState(41991) -- check, if ripple-all-state is on(1) or off(0)
  if reaper.GetPlayState()~=0 then state=0 end -- If you play/record currently, ignore the ripple-all-state by setting state=0. 

  if state==1 then return true else return false end
end


-- You probably don't need to look at the rest of the code from here on

-- You probably don't need to look at the rest of the code from here on

function main()
  -- let's get, if the sound shall be played(true) or not(false)
  local cur_state=GetCurrentState()
  
  -- Now we go to the counting of time and playing the sound-logic. 

  -- Some notes on how the number of seconds between each ping is calculated:
  -- Reaper executes this script approximately 33 times per second, so we need to have a counter-variable valled counter,
  -- to check, whether one second is gone(script was executed 33 times).
  -- We will use this variable in various ways. 
  -- For instance, everytime, the counter-variable reaches ping_delay*33, we will play the sound.
  -- To know, when to play the sound again, we check when the counter-variable is 33*seconds_between_each_ping.
  -- In that case, we will reset the value of counter to 0 to restart measuring the time again.

  -- if cur_state is true(turned on) then do the sound magic
  if cur_state==true then
    -- if the counter reaches the delay-value in seconds (delay*33) then play the sound once
    if seconds_between_each_ping~=-1 and counter==math.floor(ping_delay*33) then
      if id~=nil then
        reaper.Xen_StopSourcePreview(id)
      end
      local PCM_Source=reaper.PCM_Source_CreateFromFile(ping_sound_filename)
      id=reaper.Xen_StartSourcePreview(PCM_Source, ping_volume, false, ping_output_channel)
    elseif seconds_between_each_ping==-1 and started~=true then
      local PCM_Source=reaper.PCM_Source_CreateFromFile(ping_sound_filename)
      id=reaper.Xen_StartSourcePreview(PCM_Source, ping_volume, true, ping_output_channel)
      count=-1
      started=true
    end
    counter=counter+1
  -- if cur_state is off(false), then reset the counter and wait, so no sound is played.
  elseif cur_state==false then
    counter=-1
    started=false
    if id~=nil then
      reaper.Xen_StopSourcePreview(id)
    end
  end
  
  -- if the maximum time between two pings has been reached, reset the counter and restart counting again
  -- it waits for "33*seconds_between_each_ping" which is the number of times, Reaper executes the script in the background 
  -- in the amount of seconds between each ping
  if seconds_between_each_ping~=0 and counter>=33*seconds_between_each_ping then
    counter=0
  end
  reaper.defer(main)
end

function atexit()
  if id~=nil then
    reaper.Xen_StopSourcePreview(id)
  end
end

reaper.atexit(atexit)

-- check, if JS-extension is correctly installed
if reaper.Xen_StartSourcePreview==nil then reaper.MB("JS-extension doesn't seem to be installed...", "error", 0) return end
id=nil       -- the id of the currently playing sound; don't change
counter=0    -- counter-variable needed by the script; don't change.

main()
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-27-2022, 11:55 AM   #17
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Meo,
Yep, that is working a treat now. I have two different sounds for ripple track and ripple all and they play just fine.
Next point though. With the previous version I think when I tabbed away from Reaper so another programme had focus e.g. Firefox, the beeping wouldn't sound. the beeps only played when Reaper had the focus. Now as I'm writing this I get a beep every now and then.
Can it be done so the beeps only happen when Reaper has the focus?
Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-28-2022, 07:41 AM   #18
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Good point, I'll try my best.

Is it ok, if I concentrate on if the main-Reaper window is in focus? Other Reaper windows like dialogs might be possible too, but I need to experiment with that.
So in the worst case scenario, the beeps would definitely sound, when you focus Reaper's mainwindow, so while editing in the arrangeview, you get feedback, but not when focusing the actionlist or Media Item Properties....but only in the worst case scenario.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...

Last edited by Meo-Ada Mespotine; 05-28-2022 at 09:41 AM.
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-29-2022, 03:20 AM   #19
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Meo,
If it was just the main transport view then that wouldn't be a bad worst case scenario at all. It's bordering on the preferable. You are only going to do damage to items when in the TCP so this is where you want the audible warning. If you are in the FX chain, the param dialogue, the media explorer and so on then it isn't so important to know if ripple mode is on or off.
Also, as a blind user, a number of the floating windows aren't accessible so aren't used. The mixer window is a good example. To adjust volume and pan of a track I go to the track and use keyboard shortcuts to vary these things. So the TCP is where a blind user spends more of their time than a sighted user.
Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-29-2022, 10:58 AM   #20
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Hmmm... this sounds like a nice challenge to make the mixer accessible. I think, some APIs would allow this, IIRC, so reducing the number of needed shortcuts might be possible in conjunction with Osara...
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-30-2022, 02:05 AM   #21
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Ok, version 1.2 of the script.
This supports now playing a sound with only Reaper-windows in focus and I thought that maybe it's a good idea to have this as an option.
So you can turn this off, if you have usecases, where you always want to be pinged, even when another app is in focus.
Just set the new variable ping_only_when_reaper_is_focused in line 26 accordingly.

It also has now a toggle-state, which means, you can see if the script is running in the actionlist(on/off).
This can be used for toggle-buttons in toolbars as well, though I don't know, if toolbars are accessible.

Code:
-- Play Ping Sound every x seconds, when Ripple-All=on and Play/Rec=off
-- Meo-Ada Mespotine - 29th of May 2022 - licensed under MIT-license

-- Changelog:
-- 1.0 - initial release - 22th of May 2022
-- 1.1 - sound doesn't get cut off anymore, when running multiple instances of this script - 27th of May 2022
-- 1.2 - new option that sounds are only played, when a Reaper-window is in focus(excluding ReaScript-IDE and Consolidate Tracks-dialog), can be turned off
--       shows in actionlist now, if it's turned on(allows for toolbar-buttons) plus some internal cleanup - 29th of May 2022

-- You can modify this script to check for other states as well. For this, make a copy of this script and alter the GetCurrenState-function, so it returns true, when you want to hear the sound or false, if you don't want to.
-- The rest of the code you probably don't need to touch or look at, but I added comments in case you are curious.
-- You can set various values in the next few lines to customize, how often you want the playsound to be played, its volume,
-- where the file can be found and a delay for the first time the sound is played.


-- You can change these variables to the values you prefer:
  ping_sound_filename=reaper.GetResourcePath().."/Scripts/1.mp3" -- the path and filename of the ping-sound
  seconds_between_each_ping=7 -- the number of seconds to wait inbetween each ping; values l.5 and 17.4 are allowed too
                              -- 0, to play the sound only once and -1 to start the sound immediately and loop it until ripple=off and/or play/rec=true
  ping_volume=0.5         -- the volume of the ping-sound; 0 for off; 10 is maximum; values like 0.1 or 3.4 are allowed too.
  ping_output_channel=0 -- the hardware-output-channel of your device, that shall play the ping sound(0 for default)
  ping_delay=0      -- the number of seconds to wait, until the sound is played for the first time(0 to start playing immediately after ripple edit=on and play/rec=off)
                    -- with this, you can avoid being annoyed immediately by the sound, when you realised yourselves, that you accidentally had ripple-all on so you have 
                    -- time to turn it off before the first ping reminds you
                    -- Is ignored, when seconds_between_each_ping is set to -1.
  ping_only_when_reaper_is_focused=true -- set to true, if the ping shall only be, when Reaper or its childwindows are focused; 
                                        -- set to false, when you want to be pinged all the time, even when another app is on focus

function GetCurrentState()
  -- This is the function you need to alter, if you want to check for something else than ripple-all and play/rec.
  -- Just get the state and return true if you want to play the sound or return false, if not.
  -- The wait-time-between two pings will be done in the rest of the code outside this function, so you don't 
  -- need to bother with that. Just return true for as long as you want to have a sound played and the rest should work automatically.
  
  local state=reaper.GetToggleCommandState(41991) -- check, if ripple-all-state is on(1) or off(0)
  if reaper.GetPlayState()~=0 then state=0 end -- If you play/record currently, ignore the ripple-all-state by setting state=0. 

  if state==1 then return true else return false end
end


-- You probably don't need to look at the rest of the code from here on

function main()
  
  -- let's get first, if the Reaper window is unfocused(don't play) and if it's focused, if the 
  -- state-conditions for playing a sound are met
  local cur_state
  if IsReaperFocused()==false and ping_only_when_reaper_is_focused==true then 
    -- if the Reaper-window or any of its child-windows is not focused(means, you're in a different app), prevent soundplaying.
    cur_state=false 
  else
    -- let's get, if the sound shall be played(true) or not(false)
    cur_state=GetCurrentState()
  end
  
  -- Now we go to the counting of time and playing the sound-logic. 

  -- Some notes on how the number of seconds between each ping is calculated:
  -- Reaper executes this script approximately 33 times per second, so we need to have a counter-variable valled counter,
  -- to check, whether one second is gone(script was executed 33 times).
  -- We will use this variable in various ways. 
  -- For instance, everytime, the counter-variable reaches ping_delay*33, we will play the sound.
  -- To know, when to play the sound again, we check when the counter-variable is 33*seconds_between_each_ping.
  -- In that case, we will reset the value of counter to 0 to restart measuring the time again.
  -- In some cases, Reaper might slow down execution of this script(mouse movements or opening of some dialogs), which
  -- might to lead some slightly longer inbetween-times between two pings.
  -- If that's too annoying in practice, I'll fix it more to actual time-measuring...

  -- if cur_state is true(turned on) then do the sound magic
  if cur_state==true then
    -- if the counter reaches the delay-value in seconds (delay*33) then play the sound once
    if seconds_between_each_ping~=-1 and internal_variables_dont_change["counter"]==math.floor(ping_delay*33) then
      if internal_variables_dont_change["id"]~=nil then
        reaper.Xen_StopSourcePreview(internal_variables_dont_change["id"])
      end
      local PCM_Source=reaper.PCM_Source_CreateFromFile(ping_sound_filename)
      internal_variables_dont_change["id"]=reaper.Xen_StartSourcePreview(PCM_Source, ping_volume, false, ping_output_channel)
    elseif seconds_between_each_ping==-1 and internal_variables_dont_change["started"]~=true then
      local PCM_Source=reaper.PCM_Source_CreateFromFile(ping_sound_filename)
      internal_variables_dont_change["id"]=reaper.Xen_StartSourcePreview(PCM_Source, ping_volume, true, ping_output_channel)
      count=-1
      internal_variables_dont_change["started"]=true
    end
    internal_variables_dont_change["counter"]=internal_variables_dont_change["counter"]+1
  -- if cur_state is off(false), then reset the counter and wait, so no sound is played.
  elseif cur_state==false then
    internal_variables_dont_change["counter"]=-1
    internal_variables_dont_change["started"]=false
    if internal_variables_dont_change["id"]~=nil then
      reaper.Xen_StopSourcePreview(internal_variables_dont_change["id"])
    end
  end

  -- if the maximum time between two pings has been reached, reset the counter and restart counting again
  -- it waits for "33*seconds_between_each_ping" which is the number of times, Reaper executes the script in the background 
  -- in the amount of seconds between each ping
  if seconds_between_each_ping~=0 and internal_variables_dont_change["counter"]>=33*seconds_between_each_ping then
    internal_variables_dont_change["counter"]=0
  end
  reaper.defer(main)
end

function IsReaperFocused()
  local HWND=reaper.GetMainHwnd()
  if HWND==reaper.JS_Window_GetFocus() then return true end
  local HWND2=reaper.JS_Window_GetFocus()
  for i=0, 100 do
    if HWND==reaper.JS_Window_GetParent(HWND2) then return true end
    HWND2=reaper.JS_Window_GetParent(HWND2)
  end
  
  return false
end

function atexit()
  if internal_variables_dont_change["id"]~=nil then
    reaper.Xen_StopSourcePreview(internal_variables_dont_change["id"])
  end
  reaper.SetToggleCommandState(internal_variables_dont_change["context"][3], internal_variables_dont_change["context"][4], 0)
end

reaper.atexit(atexit)

-- check, if JS-extension is correctly installed
internal_variables_dont_change={}
if reaper.Xen_StartSourcePreview==nil then reaper.MB("JS-extension doesn't seem to be installed...", "error", 0) return end
internal_variables_dont_change["id"]=nil       -- the id of the currently playing sound; don't change
internal_variables_dont_change["counter"]=0    -- counter-variable needed by the script; don't change.
internal_variables_dont_change["context"]={reaper.get_action_context()}
reaper.SetToggleCommandState(internal_variables_dont_change["context"][3], internal_variables_dont_change["context"][4], 1)


main()
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-30-2022, 11:18 AM   #22
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Meo, yep, that does it. Working a treat. Thanks.
I get the beeping wherever I am in Reaper - TCP, midi piano roll, media explorer. When I move away to another application no more beeps.
When I view the action in the action list it now says whether the warning script is on or off which is nice. You are right that the toolbar isn't particularly accessible. I could get to the toolbar but looking in the action list is far easier.
So I'll give it more testing and I have one other friend trying it out now as well.
Thanks for fixing these nigles.
Best,
Castle
Castle Starter is offline   Reply With Quote
Old 05-31-2022, 09:09 AM   #23
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,621
Default

Quote:
Originally Posted by Castle Starter View Post
Hi Meo, yep, that does it. Working a treat. Thanks.
I get the beeping wherever I am in Reaper - TCP, midi piano roll, media explorer. When I move away to another application no more beeps.
When I view the action in the action list it now says whether the warning script is on or off which is nice. You are right that the toolbar isn't particularly accessible. I could get to the toolbar but looking in the action list is far easier.
So I'll give it more testing and I have one other friend trying it out now as well.
Thanks for fixing these nigles.
Best,
Castle
You're welcome If there's still some details missing that I could improve on, give me a note.


I'm currently thinking about making a reapack-repository for the handful accessibility scripts I already. Maybe, I could simply make it available that way via ReaPack and add variants to it, like your ripple-track-variant. Including a dialog to set the options...

That would make installing it much easier...

I give it a thought...
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 05-31-2022, 11:40 AM   #24
Castle Starter
Human being with feelings
 
Join Date: Oct 2019
Posts: 110
Default

Hi Meo,
To get both scripts (ripple track and ripple all) I have another script as follows:
code
-- Function: Run multiple scripts at start up
-- Created May 2022 by Chessel

function main()
-- Get ID for ripple track mode warning and run it
command_id = reaper.NamedCommandLookup( "_RS51cd7747efa40b5f19c589f2f90dc2eb572b28ac")
reaper.Main_OnCommand(command_id,0)

-- Get ID for ripple All mode warning and run it
command_id = reaper.NamedCommandLookup( "_RS71d2a5a4433b55b6277d06ef4802248bb16a3fbf")
reaper.Main_OnCommand(command_id,0)


end
main()
code end

Please forgive lack of indents.
I do this as the SWS Set global startup action only allows one action ID. I don't think there is anything for you to do about this. Thought I'd just let you know.

Adding a dialogue to configure the parameters sounds great but also sounds like a world of pain. It could get very complicated very quickly I feel. But if you want to take that route then I'm more than happy to test.
Might it be an idea to carry on with testing, then if all goes well, I can distribute it into the Reaper Without Peepers community. This is a group of about 4-500 Reaper users combined with SWS and the OSARA script. This will show how actually popular the idea of a ripple mode audible warning is and then if it is very popular but people say it is fiddly to set up then perhaps it would be worth investing time in this area?
Best,
Castle
Castle Starter is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 09:26 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.