Random interval generator for a given number of instances over a certain period of time

I had an intriguing problem in C # that I did not know how to do this.

I need two tracks to play on top of each other. A constant number of sound signals must be reproduced for a set period of time. One of them will have a given interval (I think, a metronome), but the other should be reproduced at random intervals.

I am not sure how to solve this second problem, a given number of audio signals reproduced at random intervals over a given amount of time.

+4
source share
4 answers

Just take this given amount of time, T. Think of it as some fairly fine-grained structure, say milliseconds. If you need to make N sounds, you need to divide the time N times. Therefore, create a loop that runs N times and at each iteration selects a random location in the time interval for the audio signal. Depending on what you do with the data after this, you may need to sort the audio signals.

+2
source

Using a random number, generate a date and time within the total time range. When you finish setting up random beeps, then the intervals will, of course, be random. Something like that:

List<DateTime> randomBeeps = new List<DateTime>(); Random rand = new Random(); for( int j = 0; j < numberBeepsNeeded; j++ ) { int randInt = rand.Next(); double percent = ((double)randInt) / Int32.MaxValue; double randTicksOfTotal = ((double)setAmountOfTime.Ticks) * percent; DateTime randomBeep = new DateTime((long)randTicksOfTotal); randomBeeps.Add(randomBeep); } 

You may need to use Convert.ToLong or something like that. Not sure if this will give you an error when converting from double to long, as it rounds it off, which is good here.

0
source

You can implement this as a series of one-time timers. As each timer (or β€œticks”) expires, you play a beep and then arbitrarily determine the duration of use for the next one-time timer. If the duration you select is a random number from 1 to 1000 (milliseconds), you will average one tick every half second.

Edit: just for fun, I thought I would say that this is an old problem for behavioral psychologists managing experiments inspired by B.F. Skinner. They sometimes use a reinforcement schedule called β€œVariable Interval,” in which the time between reinforcements varies randomly around a given average interval. See http://www.ncbi.nlm.nih.gov/pmc/articles/PMC1404199/pdf/jeabehav00190-0145.pdf for a discussion of the discussed formulas with eggs.

0
source

Something like this should do the trick (this code has not been tested ... but it compiles clean)

 using System; using System.Security.Cryptography; using System.Threading; class BeatBox : IDisposable { private RandomNumberGenerator RNG; private DateTime dtStarted; private TimeSpan TimeElapsed { get { return DateTime.Now - dtStarted; } } private TimeSpan Duration; private TimeSpan BeatInterval; private uint MinRandomInterval; private uint MaxRandomInterval; private uint RandomIntervalDomain; private Timer RegularIntervalTimer; private Timer RandomIntervalTimer; public delegate void TickHandler( object sender , bool isRandom ); public event TickHandler TickEvent; private EventWaitHandle CompletionEventWaitHandle; public BeatBox( TimeSpan duration , TimeSpan beatInterval , uint minRandomInterval , uint maxRandomInterval ) { this.RNG = RandomNumberGenerator.Create(); this.Duration = duration ; this.BeatInterval = beatInterval ; this.MinRandomInterval = minRandomInterval ; this.MaxRandomInterval = maxRandomInterval ; this.RandomIntervalDomain = ( maxRandomInterval - minRandomInterval ) + 1 ; this.dtStarted = DateTime.MinValue ; this.RegularIntervalTimer = null ; this.RandomIntervalTimer = null ; return; } private long NextRandomInterval() { byte[] entropy = new byte[sizeof(long)] ; RNG.GetBytes( entropy ); long randomValue = BitConverter.ToInt64( entropy , 0 ) & long.MaxValue; // ensure that its positive long randomoffset = ( randomValue % this.RandomIntervalDomain ); long randomInterval = this.MinRandomInterval + randomoffset; return randomInterval; } public EventWaitHandle Start() { long randomInterval = NextRandomInterval(); this.CompletionEventWaitHandle = new ManualResetEvent( false ); this.RegularIntervalTimer = new Timer( RegularBeat , null , BeatInterval , BeatInterval ); this.RandomIntervalTimer = new Timer( RandomBeat , null , randomInterval , Timeout.Infinite ); return this.CompletionEventWaitHandle; } private void RegularBeat( object timer ) { if ( this.TimeElapsed >= this.Duration ) { MarkComplete(); } else { this.TickEvent.Invoke( this , false ); } return; } private void RandomBeat( object timer ) { if ( this.TimeElapsed >= this.Duration ) { MarkComplete(); } else { this.TickEvent.Invoke( this , true ); long nextInterval = NextRandomInterval(); this.RandomIntervalTimer.Change( nextInterval , Timeout.Infinite ); } return; } private void MarkComplete() { lock ( this.CompletionEventWaitHandle ) { bool signaled = this.CompletionEventWaitHandle.WaitOne( 0 ); if ( !signaled ) { this.RegularIntervalTimer.Change( Timeout.Infinite , Timeout.Infinite ); this.RandomIntervalTimer.Change( Timeout.Infinite , Timeout.Infinite ); this.CompletionEventWaitHandle.Set(); } } return; } public void Dispose() { if ( RegularIntervalTimer != null ) { WaitHandle handle = new ManualResetEvent( false ); RegularIntervalTimer.Dispose( handle ); handle.WaitOne(); } if ( RandomIntervalTimer != null ) { WaitHandle handle = new ManualResetEvent( false ); RegularIntervalTimer.Dispose( handle ); handle.WaitOne(); } return; } } class Program { static void Main( string[] args ) { TimeSpan duration = new TimeSpan( 0 , 5 , 0 ); // run for 5 minutes total TimeSpan beatInterval = new TimeSpan( 0 , 0 , 1 ); // regular beats every 1 second uint minRandomInterval = 5; // minimum random interval is 5ms uint maxRandomInterval = 30; // maximum random interval is 30ms using ( BeatBox beatBox = new BeatBox( duration , beatInterval , minRandomInterval , maxRandomInterval ) ) { beatBox.TickEvent += TickHandler; EventWaitHandle completionHandle = beatBox.Start(); completionHandle.WaitOne(); } return; } static void TickHandler( object sender , bool isRandom ) { Console.WriteLine( isRandom ? "Random Beep!" : "Beep!" ); return; } } 
0
source

Source: https://habr.com/ru/post/1379020/


All Articles