Metronome Programmatically

All about the past, current and future webteases and the art of webteasing in general.
---
Post Reply
Philocalist
Explorer
Explorer
Posts: 51
Joined: Mon Dec 03, 2018 8:30 pm
Gender: Male
Sexual Orientation: Straight

Metronome Programmatically

Post by Philocalist »

Hello All!
I've ran into a minor crossroads I need help with.
The tease I'm making is super-interactive and variable dependent and I would like to make a metronome function to make my life easier and the tease better. It could look something like this:

Code: Select all

function metronome(bmp,timeInSeconds=undefined,strokeCount=undefined,first,second,third,fourth,fifth,sixth,seventh,eighth)
{
var beep=Sound.get("metronomeSound"); //from a cached audio
var timeStart=DateTime.now();
var count=0;

	if(timeInSeconds!=undefined)
	{
		while(timeStart+1000*timeInSeconds>DateTime.now())
		{
			if(first)
			{
				beep.play();
			}
			wait(1000*(60/bmp)); //if bmp is sixty waits a second
			if(second)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
			if(third)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
			if(fourth)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
			if(fifth)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
			if(sixth)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
			if(seventh)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
			if(eighth)
			{
				beep.play();
			}
			wait(1000*(60/bmp));
		}
	}
	else
	{
		while(count<strokeCount)
		{
			if(first)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(second)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(third)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(fourth)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(fifth)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(sixth)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(seventh)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
			if(eighth)
			{
				beep.play();
				count++;
			}
			wait(1000*(60/bmp));
		}
	}
	
}
It's kind of a napkin code, I just made it up right now, what I had trouble with is playing the sound multiple times. I haven't tested the algorithm above. And sorry for my terrible javaScript. Any ideas how it could work or why it won't? I really don't want to use longer metronome sequences because it would be a pain in the ass to make them each time dependent on variables.
Thanks for each and every reply!
kerkersklave
Explorer At Heart
Explorer At Heart
Posts: 709
Joined: Sun Jul 06, 2014 2:11 pm
Gender: Male
Sexual Orientation: Open to new ideas!
I am a: Slave

Re: Metronome Programmatically

Post by kerkersklave »

There is nothing like the wait call in Javascript. Code like that would require a separate thread to run in the background and Javascript is for the most part single threaded. (This is no longer true for some modern APIs that allow background tasks, but they still do not provide such a wait call and inside EOS you do not have access to those anyway).

Javascript has the setTimeout/setInterval functions to trigger callbacks at certain points in time. This would theoretically work, but as far as I know, these are not available in EOS. In EOS all timeouts have to be done via the timeres EOS provides.
It seems impractical to me to use that mechanism to generate single metronome ticks as you have to change the page to restart a timer.

I have done something similar by generating a bunch of metronome samples and running them on a loop. I don't think that there is currently another option.
Philocalist
Explorer
Explorer
Posts: 51
Joined: Mon Dec 03, 2018 8:30 pm
Gender: Male
Sexual Orientation: Straight

Re: Metronome Programmatically

Post by Philocalist »

kerkersklave wrote: Mon Jun 22, 2020 2:15 pm There is nothing like the wait call in Javascript. Code like that would require a separate thread to run in the background and Javascript is for the most part single threaded. (This is no longer true for some modern APIs that allow background tasks, but they still do not provide such a wait call and inside EOS you do not have access to those anyway).

Javascript has the setTimeout/setInterval functions to trigger callbacks at certain points in time. This would theoretically work, but as far as I know, these are not available in EOS. In EOS all timeouts have to be done via the timeres EOS provides.
It seems impractical to me to use that mechanism to generate single metronome ticks as you have to change the page to restart a timer.

I have done something similar by generating a bunch of metronome samples and running them on a loop. I don't think that there is currently another option.
wait is a separate, very crude and inelegant function, which traps the thread in a while loop
kerkersklave
Explorer At Heart
Explorer At Heart
Posts: 709
Joined: Sun Jul 06, 2014 2:11 pm
Gender: Male
Sexual Orientation: Open to new ideas!
I am a: Slave

Re: Metronome Programmatically

Post by kerkersklave »

The first problem is, where do you run this code? In EOS you can just run code when certain events happen, and if it does not terminate, the tease will hang.

If you do that directly in a browser, you will put a lot of load on the processor and at some point modern browsers will probably stop your script. A busy wait is just not something you can do anymore on modern systems.
Philocalist
Explorer
Explorer
Posts: 51
Joined: Mon Dec 03, 2018 8:30 pm
Gender: Male
Sexual Orientation: Straight

Re: Metronome Programmatically

Post by Philocalist »

kerkersklave wrote: Mon Jun 22, 2020 2:54 pm The first problem is, where do you run this code? In EOS you can just run code when certain events happen, and if it does not terminate, the tease will hang.

If you do that directly in a browser, you will put a lot of load on the processor and at some point modern browsers will probably stop your script. A busy wait is just not something you can do anymore on modern systems.
I was thinking of referencing the metronome each time I need it in the script/eval action. Also wait should not wait more than 4 seconds. The problem is that I don't seem to be able to play the sound more than once. And I would like to do the metronome as elegantly as possible, because it would depend on many factors.
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: Metronome Programmatically

Post by RemiHiyama »

GuideMe supports dynamic creation of metronomes with exotic beat patterns.

Which probably isn't the answer you want to get if you've already got stuff built in EOS or need other things that EOS has and GuideMe doesn't, but if this feature is really important to you...
Auto: Replaces selected instances of the word "not" with the word "definitely".
undeniable_denial
Explorer At Heart
Explorer At Heart
Posts: 109
Joined: Sat Aug 24, 2019 11:42 am
Gender: Male
Location: Germany

Re: Metronome Programmatically

Post by undeniable_denial »

I have something like this. I was planning on using it in a tease and then publish it in the forum.

I can feed it any constant number or a time-dependent callback-function, to make for example an "overdrive".

It's done using the Audio-action's stop-event, their seek-function and some syncing code.

There are some problems with it.
1. There seems to be a bug in EOS. Eventually this method causes 100% usage on one cpu-core. On my PC its after 30 minutes. On my phone after 2 minutes.
This can be worked around using a page change and a new play-action. However syncing the metronome across page changes is somewhat tricky, but it works.

2. As has been pointed out. Javascript is event-based and even on the fastest computer these events sometimes get delayed too much. There is another bug/feature in EOS that allows audio-files to be played multiple times concurrently and I could not find a way to control all these instances. This combined with the event-nature will make the metronome bug out eventually, but inevitably.

Basically it works 95% of the time, which I don't find reliable enough.

I can post it tomorrow or so. I don't think I will be using it in a tease because of the above reasons.
Philocalist
Explorer
Explorer
Posts: 51
Joined: Mon Dec 03, 2018 8:30 pm
Gender: Male
Sexual Orientation: Straight

Re: Metronome Programmatically

Post by Philocalist »

Thank you all, it was very informative. At least now I'm certain that I won't do work that could be worked around. I'm about to create a few hundred one minute metronome clips. Already got 20. Wish me strenght for the tediousness that lies ahead.
kerkersklave
Explorer At Heart
Explorer At Heart
Posts: 709
Joined: Sun Jul 06, 2014 2:11 pm
Gender: Male
Sexual Orientation: Open to new ideas!
I am a: Slave

Re: Metronome Programmatically

Post by kerkersklave »

Ah the end-event, I thought that might be an option.
The problem is that doing that via the event loop of javascript or in this case probably even EOS is bound to create some timing issues. These even loops are just not made to provide reliable realtime processing.
What one would do usually is to generate an audio stream on the fly and feed that to the audio subsystem.
Browsers do have an audio API nowadays that allows you to do that, but it is not exposed via EOS.
I also think it would be a bit too low level for EOS. It would be great to have a module in EOS to generate metronome sounds though.
Post Reply