Periklis Ntanasis:
Master's Touch

fade out

BeatKeeper: Adding a visual tick

So I have tried the obvious, which is to simply print the current beat without success.

Printing the current beat before or after writing to the audio buffer resulted the current beat not to change in sync with the sound.

However, thinking a little bit about it, it seemed pretty reasonable because each time I wrote to the audio buffer I wasn’t writing a single tick but instead a group of ticks and gaps(silence).

So, the first thing I did was to write only a pair of tick and gap each time to the audio buffer.

Here is the updated code:

public void calcSilence() {
                silence = (int) (((60/bpm)*8000)-tick);
                // I am calculating audio buffers that contain
                // a tick and a silence gap
                soundArray = new double[this.tick+this.silence];
                msg = new Message();
                msg.obj = ""+currentBeat;
        }

        public void play() {
                calcSilence();
                double[] tick = audioGenerator.getSineWave(this.tick, 8000
                                                            ,beatSound);
                double[] tock = audioGenerator.getSineWave(this.tick, 8000
                                                            ,sound);
                double silence = 0;
                int t = 0,s = 0,b = 0;
                do {
                        for(int i=0;i<soundArray.length&&play;i++) {
                                if(t<this.tick) {
                                        if(b == 0)
                                                soundArray[i] = tock[t];
                                        else
                                                soundArray[i] = tick[t];
                                        t++;
                                } else {
                                        soundArray[i] = silence;
                                        s++;
                                        if(s >= this.silence) {
                                                t = 0;
                                                s = 0;
                                                b++;
                                                if(b > (this.beat-1))
                                                        b = 0;
                                        }
                                }
                        }
                        msg = new Message();
                        msg.obj = ""+currentBeat;
                        // write the current beat right before or after
                        // writing to the audio buffer
                        if(bpm < 100)
                                mHandler.sendMessage(msg);
                        audioGenerator.writeSound(soundArray);
                        if(bpm >= 100)
                                mHandler.sendMessage(msg);
                        currentBeat++;
                        if(currentBeat > beat)
                                currentBeat = 1;
                } while(play);
        }

As you can see the trick is to calculate the buffer size each time the beats per minute (bpm) change.

Some times I am printing the current beat number before writing to the audio buffer and some times after, because the bpm is low or high and the user has to see the current beat as he is listening to the sound. Doing otherwise would give a false sense to the user about the number of the current beat.

The number of 100 bpm that I am using to decide whether to print before or after was picked after some experimentation.

Here is a pic about this in action:

current beat in action

Current beat is the third value.

I have updated BeatKeeper repo so full code about this can be found here.

The metronome visualization that I have implemented is very simple. If one implements another one, more eye candy, feel free to leave a comment about it.

Comments

fade out