2004-03-12 08:21:26 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
* Copyright (C) 2004 Matthias Wientapper, 2014-2015 Thomas Orgis
|
2004-03-12 08:21:26 +00:00
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2004-03-12 08:21:26 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
* TODO:
|
|
|
|
* - Think about generating the sounds on startup with SWCODEC.
|
2004-03-12 08:21:26 +00:00
|
|
|
****************************************************************************/
|
2008-10-30 14:39:20 +00:00
|
|
|
#include "plugin.h"
|
2008-11-20 11:27:31 +00:00
|
|
|
#include "lib/pluginlib_actions.h"
|
2010-08-24 14:30:46 +00:00
|
|
|
#include "lib/pluginlib_exit.h"
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
#include "fixedpoint.h"
|
|
|
|
|
|
|
|
/* About time resolution:
|
|
|
|
1000 means 1 ms resolution. It should get better with higher values
|
|
|
|
in theory, but in practice, too small timer intervals increase the
|
|
|
|
chance of being missed and make the metronome lag behind. Mean tempo
|
|
|
|
still works out with very small divider values (29 even) as long as
|
|
|
|
the rounding error compensation is active, although beat intervals
|
|
|
|
become jerky. You compromise between long-term accuracy and steadyness
|
|
|
|
from one beat to the next.
|
|
|
|
|
|
|
|
A drift you have to accept comes just from the audio clock itself, or even
|
|
|
|
from the difference between clocks in the device. The Sansa Clip+ has around
|
|
|
|
0.04 % error in audio frequency using the "good" PLLB. I presume that the
|
|
|
|
difference between timing using PLLA and PLLB is at least that big. Something
|
|
|
|
up to 40 ms time difference over one minute when comparing to an external
|
|
|
|
reference or just the metronome plugin with playback of a prepared PCM track
|
|
|
|
is to be expected.
|
|
|
|
|
|
|
|
Also, since playback on SWCODEC is not allowed to happen inside the timer
|
|
|
|
callback, there is a delay introduced by the main loop scheduling. This
|
|
|
|
could be compensated for by delaying the audio depending on a counter
|
|
|
|
incremented since the period elapsed in the callback, at the price of
|
|
|
|
putting the display out of sync. On a Clip+, the schedule delay isn't
|
|
|
|
biggest problem (drift for fine timer resolution is).
|
|
|
|
|
|
|
|
All in all, 1 ms is too small, 2 ms seems to work fine ...
|
|
|
|
4 ms might still be cool, too.
|
|
|
|
*/
|
|
|
|
#if defined(SIMULATOR)
|
|
|
|
/* Simulator really wants 1024. Not 1000, not 512, only 1024.
|
|
|
|
Otherwise it is strangely slow. */
|
|
|
|
static const unsigned int timerfreq_div = 1024;
|
2008-10-30 14:39:20 +00:00
|
|
|
#else
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
static const unsigned int timerfreq_div = 500; /* 2 ms resolution */
|
2008-10-30 14:39:20 +00:00
|
|
|
#endif
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* actual (not quarter) beats per minute above which display blinking
|
|
|
|
is deactivated (since it is not needed anymore and because of performance
|
|
|
|
issues) */
|
|
|
|
static const unsigned int blinklimit = 135;
|
|
|
|
|
|
|
|
enum metronome_errors
|
|
|
|
{
|
|
|
|
MERR_NOTHING = 0
|
|
|
|
, MERR_MISSING
|
|
|
|
, MERR_OOM
|
|
|
|
, MERR_TEMPO
|
|
|
|
, MERR_METER
|
|
|
|
, MERR_VOLUME
|
|
|
|
, MERR_PATTERN
|
|
|
|
};
|
|
|
|
|
|
|
|
#define PART_MAX 10 /* maximum count of programmed parts */
|
2008-10-30 14:39:20 +00:00
|
|
|
|
2010-05-20 17:41:28 +00:00
|
|
|
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) \
|
2015-07-19 23:50:26 +00:00
|
|
|
|| (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SAMSUNG_YH820_PAD)
|
2010-05-20 17:41:28 +00:00
|
|
|
#define MET_SYNC
|
|
|
|
#endif
|
|
|
|
|
plugins: Improve usability of iPod keymaps
- Reduce need to press multiple buttons at
the same time to quit a plugin
- Have "Menu" be default way to quit plugins or
to access plugin menu
- Fall back to (Long) "Select" or Long "Menu"
in cases where Menu button isn't available
(e.g. in ImageViewer and many games)
out of scope:
boomshine, lua_scripts, Rockpaint,
Doom, Duke3D, Pacbox, Quake,
Sgt-Puzzles, Wolf3D, XWorld,
Minesweeper, Pixel Painter, Spacerocks
Change-Id: I6d4dc7174695fe4b8ee9cbaccb21bdbfe6af5c48
2022-12-18 20:13:15 +00:00
|
|
|
#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \
|
|
|
|
|| (CONFIG_KEYPAD == IPOD_3G_PAD) \
|
|
|
|
|| (CONFIG_KEYPAD == IPOD_4G_PAD)
|
|
|
|
#define METRONOME_QUIT PLA_UP
|
|
|
|
#else
|
2010-05-20 17:41:28 +00:00
|
|
|
#define METRONOME_QUIT PLA_EXIT
|
plugins: Improve usability of iPod keymaps
- Reduce need to press multiple buttons at
the same time to quit a plugin
- Have "Menu" be default way to quit plugins or
to access plugin menu
- Fall back to (Long) "Select" or Long "Menu"
in cases where Menu button isn't available
(e.g. in ImageViewer and many games)
out of scope:
boomshine, lua_scripts, Rockpaint,
Doom, Duke3D, Pacbox, Quake,
Sgt-Puzzles, Wolf3D, XWorld,
Minesweeper, Pixel Painter, Spacerocks
Change-Id: I6d4dc7174695fe4b8ee9cbaccb21bdbfe6af5c48
2022-12-18 20:13:15 +00:00
|
|
|
#endif
|
2010-05-20 17:41:28 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SCROLLWHEEL
|
|
|
|
#define METRONOME_VOL_UP PLA_SCROLL_FWD
|
|
|
|
#define METRONOME_VOL_UP_REP PLA_SCROLL_FWD_REPEAT
|
|
|
|
#define METRONOME_VOL_DOWN PLA_SCROLL_BACK
|
|
|
|
#define METRONOME_VOL_DOWN_REP PLA_SCROLL_BACK_REPEAT
|
|
|
|
#else
|
|
|
|
#define METRONOME_VOL_UP PLA_UP
|
|
|
|
#define METRONOME_VOL_DOWN PLA_DOWN
|
|
|
|
#define METRONOME_VOL_UP_REP PLA_UP_REPEAT
|
|
|
|
#define METRONOME_VOL_DOWN_REP PLA_DOWN_REPEAT
|
|
|
|
#endif
|
2007-07-29 03:43:37 +00:00
|
|
|
#define METRONOME_LEFT PLA_LEFT
|
|
|
|
#define METRONOME_RIGHT PLA_RIGHT
|
2006-11-17 00:50:35 +00:00
|
|
|
#define METRONOME_LEFT_REP PLA_LEFT_REPEAT
|
|
|
|
#define METRONOME_RIGHT_REP PLA_RIGHT_REPEAT
|
2010-05-20 17:41:28 +00:00
|
|
|
#define METRONOME_TAP PLA_SELECT_REL
|
|
|
|
#define METRONOME_PAUSE PLA_CANCEL
|
|
|
|
#define METRONOME_PLAY PLA_SELECT_REPEAT
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
#define METRONOME_START PLA_SELECT
|
2006-03-30 21:17:19 +00:00
|
|
|
|
2010-05-20 17:41:28 +00:00
|
|
|
#ifdef MET_SYNC
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
enum{ METRONOME_SYNC = LAST_PLUGINLIB_ACTION+1 };
|
2006-12-03 16:49:36 +00:00
|
|
|
static const struct button_mapping iriver_syncaction[] =
|
2006-11-16 02:53:44 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
{ METRONOME_SYNC, BUTTON_REC, BUTTON_NONE },
|
2009-11-17 22:10:22 +00:00
|
|
|
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_PLUGIN)
|
2006-11-16 02:53:44 +00:00
|
|
|
};
|
2007-07-29 05:30:04 +00:00
|
|
|
#endif /* IRIVER_H100_PAD||IRIVER_H300_PAD */
|
2006-01-10 02:51:50 +00:00
|
|
|
|
2008-11-25 13:48:40 +00:00
|
|
|
const struct button_mapping *plugin_contexts[] =
|
|
|
|
{
|
2010-05-20 17:41:28 +00:00
|
|
|
pla_main_ctx,
|
|
|
|
#if defined(MET_SYNC)
|
2007-07-29 05:30:04 +00:00
|
|
|
iriver_syncaction,
|
|
|
|
#endif
|
|
|
|
};
|
2008-01-23 08:25:04 +00:00
|
|
|
#define PLA_ARRAY_COUNT sizeof(plugin_contexts)/sizeof(plugin_contexts[0])
|
2006-01-10 02:51:50 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* raw PCM */
|
|
|
|
static signed short tick_sound[] =
|
|
|
|
{
|
|
|
|
32767,32764,32767,32767,32763,32767,32762,32767,32765,32767,32767
|
|
|
|
,32766,32767,32766,32767,32767,32765,32767,32764,32767,32764,32767
|
|
|
|
,32763,-32764,-32768,-32766,-32768,-32768,-32767,-32767,-32767,-32765,-32768
|
|
|
|
,-32764,-32768,-32768,-32766,-32768,-32764,-32768,-32766,-32767,-32768,-32767
|
|
|
|
,-32766,32763,32767,32763,32767,32767,32766,32767,32766,32767,32765
|
|
|
|
,32767,32763,32767,32766,32767,32766,32767,32763,32767,32765,32767
|
|
|
|
,32767,-32768,-32765,-32768,-32767,-32765,-32767,-32765,-32768,-32764,-32768
|
|
|
|
,-32766,-32768,-32768,-32766,-32767,-32768,-32764,-32768,-32764,-32768,-32768
|
|
|
|
,-32766,32716,32668,32620,32564,32520,32467,32418,32370,32316,32272
|
|
|
|
,32214,32176,32114,32074,32020,31972,31922,31873,31823,31775,31726
|
|
|
|
,31676,-31627,-31579,-31530,-31479,-31433,-31383,-31333,-31287,-31236,-31188
|
|
|
|
,-31141,-31090,-31042,-30998,-30943,-30899,-30849,-30800,-30757,-30702,-30659
|
|
|
|
,-30609,30561,30515,30463,30422,30365,30326,30273,30229,30177,30135
|
|
|
|
,30084,30035,29995,29936,29903,29844,29802,29755,29706,29661,29614
|
|
|
|
,29565,-29519,-29472,-29426,-29381,-29331,-29288,-29239,-29191,-29149,-29099
|
|
|
|
,-29055,-29007,-28962,-28914,-28871,-28821,-28779,-28730,-28685,-28638,-28596
|
|
|
|
,-28544,28496,28463,28404,28371,28314,28278,28225,28185,28136,28093
|
|
|
|
,28048,28001,27956,27912,27865,27824,27773,27736,27682,27646,27593
|
|
|
|
,27555,-27509,-27462,-27418,-27375,-27328,-27286,-27239,-27200,-27145,-27116
|
|
|
|
,-27055,-27026,-26972,-26930,-26891,-26838,-26805,-26750,-26716,-26663,-26630
|
|
|
|
,-26575,26534,26495,26448,26408,26360,26324,26272,26235,26188,26149
|
|
|
|
,26101,26061,26016,25976,25930,25888,25847,25800,25763,25714,25676
|
|
|
|
,25632,-25589,-25547,-25505,-25461,-25419,-25376,-25337,-25291,-25251,-25209
|
|
|
|
,-25162,-25129,-25078,-25043,-24995,-24960,-24910,-24876,-24830,-24787,-24751
|
|
|
|
,-24703,24663,24622,24583,24539,24499,24456,24418,24374,24334,24292
|
|
|
|
,24252,24209,24173,24124,24092,24042,24011,23960,23930,23879,23845
|
|
|
|
,23803,-23762,-23722,-23680,-23644,-23597,-23562,-23518,-23482,-23437,-23402
|
|
|
|
,-23357,-23320,-23281,-23236,-23203,-23158,-23119,-23082,-23040,-23000,-22962
|
|
|
|
,-22922,22885,22837,22809,22759,22728,22685,22644,22608,22567,22528
|
|
|
|
,22491,22449,22412,22372,22334,22295,22254,22221,22173,22146,22096
|
|
|
|
,22066,-22026,-21984,-21947,-21911,-21867,-21836,-21790,-21757,-21719,-21677
|
|
|
|
,-21644,-21601,-21567,-21526,-21489,-21454,-21411,-21378,-21337,-21301,-21263
|
|
|
|
,-21226,21189,21151,21111,21077,21036,21002,20964,20926,20889,20852
|
|
|
|
,20814,20779,20741,20703,20666,20632,20590,20562,20512,20490,20440
|
|
|
|
,20416,-20380,-20331,-20303,-20261,-20230,-20188,-20158,-20114,-20085,-20045
|
|
|
|
,-20009,-19975,-19935,-19904,-19864,-19829,-19797,-19753,-19726,-19685,-19650
|
|
|
|
,-19616,19580,19544,19508,19471,19441,19397,19373,19325,19301,19256
|
|
|
|
,19229,19189,19155,19122,19081,19055,19013,18980,18947,18908,18879
|
|
|
|
,18840,-18807,-18771,-18739,-18701,-18669,-18634,-18600,-18564,-18531,-18497
|
|
|
|
,-18461,-18430,-18392,-18360,-18326,-18291,-18258,-18223,-18191,-18154,-18123
|
|
|
|
,-18088,18055,18019,17989,17953,17919,17887,17853,17817,17791,17746
|
|
|
|
,17726,17680,17656,17619,17585,17555,17519,17488,17453,17423,17385
|
|
|
|
,17359,17320,-17287,-17261,-17220,-17196,-17156,-17128,-17093,-17062,-17029
|
|
|
|
,-16996,-16966,-16929,-16901,-16868,-16834,-16804,-16769,-16741,-16705,-16675
|
|
|
|
,-16644,-16609,16579,16545,16519,16479,16455,16419,16388,16359,16321
|
|
|
|
,16300,16256,16235,16198,16166,16141,16102,16076,16043,16011,15981
|
|
|
|
,15950,15920,-15891,-15852,-15832,-15789,-15768,-15732,-15703,-15672,-15642
|
|
|
|
,-15609,-15582,-15548,-15521,-15487,-15459,-15426,-15401,-15364,-15339,-15305
|
|
|
|
,-15275,-15250,15219,15184,15159,15122,15101,15061,15041,15002,14981
|
|
|
|
,14944,14919,14886,14858,14829,14797,14772,14736,14715,14675,14657
|
|
|
|
,14617,14598,-14567,-14533,-14506,-14475,-14447,-14419,-14389,-14358,-14334
|
|
|
|
,-14299,-14277,-14241,-14218,-14186,-14158,-14131,-14100,-14072,-14046,-14012
|
|
|
|
,-13991,-13955,13927,13904,13873,13844,13819,13787,13761,13732,13706
|
|
|
|
,13674,13651,13619,13590,13570,13530,13516,13475,13457,13423,13401
|
|
|
|
,13368,13345,-13317,-13287,-13260,-13234,-13204,-13178,-13152,-13122,-13098
|
|
|
|
,-13068,-13043,-13013,-12990,-12958,-12937,-12902,-12884,-12849,-12829,-12798
|
|
|
|
,-12771,-12746,12718,12693,12663,12641,12611,12586,12559,12531,12510
|
|
|
|
,12475,12459,12421,12408,12367,12357,12315,12301,12268,12244,12218
|
|
|
|
,12194,12164,-12140,-12113,-12093,-12056,-12043,-12008,-11987,-11961,-11931
|
|
|
|
,-11911,-11884,-11855,-11836,-11804,-11782,-11757,-11729,-11708,-11679,-11655
|
|
|
|
,-11631,-11601,11574,11560,11525,11508,11479,11454,11431,11403,11382
|
|
|
|
,11356,11329,11307,11279,11260,11229,11211,11179,11161,11133,11110
|
|
|
|
,11085,11061,-11038,-11010,-10991,-10960,-10944,-10913,-10893,-10866,-10845
|
|
|
|
,-10818,-10796,-10772,-10747,-10725,-10699,-10676,-10653,-10629,-10605,-10580
|
|
|
|
,-10561,-10531,10507,10491,10461,10442,10416,10394,10369,10350,10319
|
|
|
|
,10305,10276,10252,10236,10202,10190,10160,10138,10117,10093,10070
|
|
|
|
,10050,10020,-9997,-9984,-9953,-9935,-9912,-9885,-9871,-9840,-9823
|
|
|
|
,-9799,-9773,-9756,-9730,-9710,-9687,-9664,-9642,-9620,-9598,-9576
|
|
|
|
,-9554,-9532,9510,9488,9466,9444,9419,9405,9374,9361,9331
|
|
|
|
,9314,9293,9268,9250,9225,9206,9184,9160,9143,9118,9098
|
|
|
|
,9077,9053,-9029,-9018,-8988,-8973,-8948,-8928,-8906,-8888,-8862
|
|
|
|
,-8848,-8819,-8805,-8780,-8760,-8740,-8720,-8695,-8681,-8653,-8638
|
|
|
|
,-8615,-8594,8573,8556,8531,8515,8492,8472,8451,8433,8409
|
|
|
|
,8393,8368,8354,8326,8315,8284,8277,8243,8236,8206,8192
|
|
|
|
,8170,8151,-8133,-8107,-8095,-8068,-8054,-8030,-8014,-7991,-7975
|
|
|
|
,-7953,-7933,-7916,-7894,-7876,-7857,-7836,-7818,-7799,-7778,-7761
|
|
|
|
,-7740,-7720,7700,7684,7665,7645,7626,7610,7582,7577,7545
|
|
|
|
,7534,7513,7493,7477,7455,7438,7419,7402,7379,7368,7341
|
|
|
|
,7328,7307,-7289,-7272,-7250,-7237,-7216,-7196,-7183,-7157,-7146
|
|
|
|
,-7123,-7108,-7091,-7065,-7058,-7030,-7020,-6998,-6979,-6965,-6944
|
|
|
|
,-6927,-6911,6895,6870,6859,6836,6824,6800,6790,6763,6755
|
|
|
|
,6730,6717,6699,6679,6667,6642,6632,6610,6596,6574,6564
|
|
|
|
,6539,6529,6507,-6492,-6474,-6457,-6442,-6422,-6406,-6392,-6371
|
|
|
|
,-6358,-6338,-6322,-6306,-6291,-6269,-6259,-6237,-6223,-6206,-6190
|
|
|
|
,-6172,-6157,-6139,6123,6108,6088,6077,6057,6043,6025,6010
|
|
|
|
,5992,5978,5962,5944,5928,5914,5897,5879,5869,5844,5837
|
|
|
|
,5816,5799,5789,-5773,-5750,-5742,-5720,-5710,-5687,-5680,-5656
|
|
|
|
,-5648,-5627,-5613,-5600,-5581,-5568,-5552,-5534,-5525,-5501,-5496
|
|
|
|
,-5470,-5464,-5443,5430,5413,5402,5383,5370,5353,5343,5320
|
|
|
|
,5314,5292,5280,5267,5248,5237,5219,5208,5190,5176,5162
|
|
|
|
,5148,5131,5121,-5107,-5086,-5077,-5058,-5047,-5030,-5017,-5002
|
|
|
|
,-4990,-4971,-4963,-4941,-4935,-4915,-4902,-4892,-4869,-4867,-4841
|
|
|
|
,-4836,-4816,-4806,4792,4774,4767,4744,4740,4716,4712,4692
|
|
|
|
,4680,4668,4649,4642,4624,4612,4599,4584,4570,4560,4541
|
|
|
|
,4535,4513,4508,-4496,-4472,-4467,-4450,-4437,-4427,-4407,-4401
|
|
|
|
,-4384,-4372,-4358,-4346,-4331,-4322,-4305,-4294,-4281,-4266,-4257
|
|
|
|
,-4240,-4231,-4216,4204,4190,4180,4162,4156,4137,4131,4111
|
|
|
|
,4104,4091,4075,4068,4048,4043,4026,4016,4002,3990,3980
|
|
|
|
,3962,3957,3938,-3926,-3919,-3904,-3892,-3882,-3866,-3858,-3843
|
|
|
|
,-3833,-3820,-3810,-3792,-3789,-3769,-3762,-3751,-3732,-3730,-3710
|
|
|
|
,-3704,-3689,-3678,3666,3656,3640,3637,3615,3613,3594,3586
|
|
|
|
,3576,3560,3555,3537,3529,3518,3504,3497,3481,3473,3462
|
|
|
|
,3447,3441,3425,-3414,-3406,-3394,-3383,-3372,-3359,-3353,-3336
|
|
|
|
,-3330,-3316,-3306,-3295,-3287,-3270,-3266,-3251,-3241,-3233,-3218
|
|
|
|
,-3210,-3197,-3192,3182,3160,3165,3139,3140,3121,3116,3104
|
|
|
|
,3093,3083,3075,3057,3058,3038,3033,3021,3009,3003,2990
|
|
|
|
,2981,2969,2960,-2947,-2943,-2928,-2921,-2910,-2898,-2891,-2881
|
|
|
|
,-2868,-2863,-2846,-2846,-2826,-2824,-2810,-2800,-2795,-2779,-2774
|
|
|
|
,-2763,-2751,-2746,2735,2724,2715,2705,2697,2682,2682,2662
|
|
|
|
,2663,2645,2641,2629,2620,2612,2602,2592,2585,2572,2566
|
|
|
|
,2557,2544,2540,-2530,-2520,-2508,-2503,-2492,-2482,-2477,-2463
|
|
|
|
,-2457,-2447,-2439,-2430,-2419,-2416,-2398,-2399,-2382,-2380,-2365
|
|
|
|
,-2364,-2346,-2345,2335,2324,2316,2308,2301,2290,2281,2275
|
|
|
|
,2263,2262,2241,2250,2220,2232,2211,2208,2199,2189,2180
|
|
|
|
,2177,2161,2163,-2154,-2137,-2138,-2119,-2122,-2102,-2107,-2087
|
|
|
|
,-2088,-2073,-2073,-2055,-2057,-2040,-2040,-2027,-2022,-2013,-2005
|
|
|
|
,-1997,-1991,-1981,1973,1967,1959,1953,1940,1941,1922,1928
|
|
|
|
,1908,1911,1892,1896,1879,1882,1862,1866,1850,1847,1840
|
|
|
|
,1829,1827,1815,-1809,-1802,-1797,-1785,-1784,-1770,-1768,-1757
|
|
|
|
,-1755,-1742,-1740,-1729,-1724,-1716,-1711,-1701,-1697,-1688,-1682
|
|
|
|
,-1676,-1665,-1663,1654,1649,1638,1637,1624,1622,1611,1611
|
|
|
|
,1594,1599,1582,1582,1573,1566,1560,1554,1547,1538,1538
|
|
|
|
,1523,1524,1512,1509,-1502,-1493,-1491,-1480,-1478,-1469,-1462
|
|
|
|
,-1458,-1450,-1444,-1441,-1427,-1431,-1414,-1418,-1405,-1400,-1397
|
|
|
|
,-1385,-1388,-1371,-1376,1370,1354,1355,1345,1341,1334,1329
|
|
|
|
,1323,1316,1311,1305,1299,1294,1287,1282,1276,1270,1266
|
|
|
|
,1255,1258,1244,1244,-1239,-1226,-1231,-1212,-1220,-1205,-1202
|
|
|
|
,-1199,-1190,-1186,-1182,-1173,-1171,-1163,-1158,-1156,-1145,-1145
|
|
|
|
,-1136,-1131,-1128,-1121,1116,1111,1106,1100,1094,1092,1082
|
|
|
|
,1084,1068,1075,1061,1061,1053,1047,1047,1037,1036,1025
|
|
|
|
,1027,1016,1017,1007,-1005,-996,-998,-986,-986,-980,-973
|
|
|
|
,-973,-962,-962,-956,-949,-949,-939,-938,-931,-929,-920
|
|
|
|
,-921,-911,-911,-903,899,896,891,885,880,881,869
|
|
|
|
,873,858,863,853,851,847,840,840,829,833,819
|
|
|
|
,826,811,815,804,-801,-800,-794,-788,-791,-778,-780
|
|
|
|
,-774,-766,-771,-755,-764,-747,-754,-742,-743,-736,-734
|
|
|
|
,-728,-727,-718,-720,715,708,708,699,703,687,697
|
|
|
|
,681,687,675,679,665,675,657,665,653,654,648
|
|
|
|
,646,642,637,634,-629,-629,-621,-623,-614,-615,-607
|
|
|
|
,-607,-602,-599,-594,-594,-586,-588,-577,-583,-571,-574
|
|
|
|
,-567,-564,-562,-559,557,548,552,541,546,532,542
|
|
|
|
,527,531,524,522,521,515,513,509,507,504,500
|
|
|
|
,497,495,490,489,-485,-482,-479,-476,-474,-468,-470
|
|
|
|
,-462,-462,-458,-455,-454,-449,-447,-443,-442,-437,-437
|
|
|
|
,-432,-429,-429,-422,420,419,417,412,411,409,404
|
|
|
|
,403,400,397,394,393,388,388,382,384,375,381
|
|
|
|
,371,372,369,364,-360,-365,-355,-360,-351,-354,-347
|
|
|
|
,-347,-345,-340,-341,-336,-335,-331,-333,-323,-329,-322
|
|
|
|
,-319,-321,-314,-316,314,308,308,303,304,300,298
|
|
|
|
,297,292,294,288,288,285,281,285,275,279,276
|
|
|
|
,270,272,269,264,-260,-267,-257,-261,-256,-254,-254
|
|
|
|
,-249,-250,-247,-244,-245,-238,-242,-235,-237,-233,-232
|
|
|
|
,-229,-229,-225,-225,222,222,218,218,214,215,211
|
|
|
|
,212,206,210,201,206,202,199,199,197,192,197
|
|
|
|
,191,188,192,183,-185,-179,-189,-174,-183,-177,-174
|
|
|
|
,-178,-169,-174,-168,-169,-167,-165,-165,-161,-162,-158
|
|
|
|
,-160,-155,-155,-155,154,149,151,148,147,146,143
|
|
|
|
,145,138,144,136,139,136,134,136,129,135,125
|
|
|
|
,134,123,130,120,-119,-126,-118,-123,-116,-122,-111
|
|
|
|
,-120,-113,-111,-115,-108,-111,-109,-108,-104,-107,-103
|
|
|
|
,-106,-99,-104,-94,93,100,95,98,93,97,88
|
|
|
|
,96,85,96,84,91,85,84,89,81,84,82
|
|
|
|
,79,84,75,82,75,-76,-75,-76,-73,-74,-71
|
|
|
|
,-73,-70,-68,-72,-65,-70,-65,-65,-67,-61,-66
|
|
|
|
,-62,-60,-62,-61,-57,54,64,52,61,52,57
|
|
|
|
,54,54,53,53,50,53,48,53,45,53,43
|
|
|
|
,51,45,45,47,42,-41,-45,-43,-40,-44,-39
|
|
|
|
,-42,-40,-38,-38,-40,-36,-39,-34,-39,-32,-37
|
|
|
|
,-33,-34,-34,-34,-29,28,35,28,32,29,30
|
|
|
|
,27,31,27,28,27,26,27,24,30,20,28
|
|
|
|
,21,27,20,27,18,-19,-23,-21,-22,-19,-23
|
|
|
|
,-16,-24,-15,-23,-15,-21,-16,-17,-20,-14,-19
|
|
|
|
,-14,-18,-13,-19,-11,11,18,10,19,8,17
|
|
|
|
,13,10,18,5,18,7,16,8,12,11,10
|
|
|
|
,10,12,6,14,5,-4,-14,-5,-10,-10,-5
|
|
|
|
,-11,-6,-8,-8,-6,-9,-5,-7,-8,-2,-12
|
|
|
|
,-1,-8,-6,-4,-7,6,5,4,7,2,6
|
|
|
|
,4,3,8,1,4,4,4,3,5,1,5
|
|
|
|
,3,1,5,2,3,-1,-5,-2,0,-5,1
|
|
|
|
,-6,2,-6,3,-6,1,-5,2,-6,5,-8
|
|
|
|
,4,-6,3,-5,3,-2,2,1,0,1,4
|
|
|
|
,-5,6,-3,1,3,-2,3,-3,5,-5,5
|
|
|
|
,-1,0,0,2,-3,4,-3,0,1,-1,-1
|
|
|
|
,2,-2,1,-1,0,1,-1,0,0,0,1
|
|
|
|
,-1,1,-2,2,-1,1,0,-3,5,-5,4
|
|
|
|
,-1,-2,2,-1,1,0,-1,1,-1,2,-3
|
|
|
|
,3,-3
|
|
|
|
};
|
|
|
|
static signed short tock_sound[] =
|
|
|
|
{
|
|
|
|
32767,32761,32767,32762,32767,32763,32767,32765,32767,32767,32766
|
|
|
|
,32767,32764,32767,32765,32767,32763,32767,32761,32767,32765,32767
|
|
|
|
,32766,32767,32766,32767,32767,32764,32767,32763,32767,32767,32766
|
|
|
|
,32767,32766,32767,32767,32765,32767,32763,32767,32761,32767,32764
|
|
|
|
,32767,-32766,-32768,-32765,-32767,-32768,-32762,-32768,-32762,-32768,-32768
|
|
|
|
,-32765,-32768,-32765,-32768,-32766,-32766,-32766,-32766,-32768,-32766,-32768
|
|
|
|
,-32766,-32768,-32767,-32768,-32766,-32768,-32767,-32767,-32768,-32763,-32768
|
|
|
|
,-32765,-32768,-32768,-32765,-32768,-32767,-32768,-32768,-32767,-32766,-32768
|
|
|
|
,-32767,32720,32666,32619,32567,32516,32471,32414,32373,32314,32270
|
|
|
|
,32220,32167,32123,32068,32023,31970,31924,31872,31824,31775,31725
|
|
|
|
,31678,31625,31581,31527,31482,31431,31383,31334,31286,31238,31185
|
|
|
|
,31144,31087,31046,30993,30947,30898,30848,30804,30750,30709,30653
|
|
|
|
,30614,-30566,-30509,-30470,-30415,-30371,-30322,-30276,-30226,-30181,-30131
|
|
|
|
,-30085,-30039,-29988,-29945,-29894,-29849,-29800,-29756,-29707,-29658,-29617
|
|
|
|
,-29562,-29522,-29473,-29425,-29380,-29334,-29283,-29242,-29193,-29145,-29103
|
|
|
|
,-29051,-29011,-28959,-28917,-28866,-28827,-28773,-28735,-28682,-28641,-28591
|
|
|
|
,-28550,28503,28457,28407,28369,28316,28275,28229,28182,28137,28094
|
|
|
|
,28044,28006,27952,27915,27864,27823,27775,27734,27682,27645,27597
|
|
|
|
,27550,27513,27455,27426,27368,27333,27284,27240,27197,27152,27105
|
|
|
|
,27069,27012,26982,26926,26891,26841,26799,26756,26712,26666,26628
|
|
|
|
,26574,-26528,-26502,-26443,-26410,-26362,-26318,-26277,-26233,-26189,-26147
|
|
|
|
,-26103,-26059,-26019,-25973,-25931,-25888,-25846,-25801,-25763,-25714,-25675
|
|
|
|
,-25633,-25587,-25549,-25502,-25463,-25419,-25378,-25333,-25294,-25249,-25208
|
|
|
|
,-25167,-25123,-25084,-25037,-25000,-24954,-24917,-24871,-24832,-24788,-24748
|
|
|
|
,-24706,24665,24622,24582,24539,24501,24454,24420,24371,24336,24292
|
|
|
|
,24251,24212,24167,24131,24084,24052,24001,23969,23921,23886,23842
|
|
|
|
,23804,23760,23724,23678,23644,23598,23561,23521,23478,23440,23401
|
|
|
|
,23356,23324,23275,23243,23197,23161,23118,23082,23039,23003,22959
|
|
|
|
,22922,-22882,-22844,-22801,-22763,-22729,-22679,-22653,-22601,-22569,-22529
|
|
|
|
,-22488,-22453,-22409,-22374,-22331,-22297,-22254,-22220,-22176,-22141,-22100
|
|
|
|
,-22064,-22024,-21985,-21947,-21910,-21869,-21833,-21794,-21754,-21721,-21675
|
|
|
|
,-21645,-21601,-21566,-21529,-21486,-21455,-21410,-21380,-21335,-21304,-21258
|
|
|
|
,-21232,21195,21144,21118,21072,21038,21003,20960,20932,20882,20858
|
|
|
|
,20810,20781,20740,20703,20668,20628,20595,20557,20518,20483,20447
|
|
|
|
,20409,20374,20336,20299,20265,20225,20194,20150,20123,20079,20047
|
|
|
|
,20008,19975,19937,19902,19866,19827,19797,19755,19725,19682,19654
|
|
|
|
,19614,-19581,-19540,-19512,-19471,-19437,-19405,-19362,-19335,-19292,-19264
|
|
|
|
,-19223,-19194,-19151,-19124,-19082,-19053,-19014,-18980,-18946,-18911,-18876
|
|
|
|
,-18842,-18804,-18775,-18735,-18704,-18668,-18634,-18598,-18568,-18527,-18500
|
|
|
|
,-18460,-18428,-18394,-18360,-18324,-18295,-18254,-18225,-18190,-18154,-18124
|
|
|
|
,-18087,18054,18021,17987,17953,17921,17884,17855,17818,17786,17754
|
|
|
|
,17718,17685,17654,17619,17586,17554,17519,17488,17454,17421,17387
|
|
|
|
,17358,17319,17295,17251,17230,17186,17164,17123,17096,17061,17028
|
|
|
|
,16996,16967,16929,16902,16865,16837,16801,16774,16736,16708,16675
|
|
|
|
,16641,16612,-16578,-16549,-16513,-16486,-16449,-16423,-16385,-16361,-16321
|
|
|
|
,-16297,-16260,-16233,-16198,-16169,-16137,-16102,-16080,-16038,-16017,-15976
|
|
|
|
,-15954,-15914,-15892,-15855,-15826,-15796,-15762,-15735,-15702,-15673,-15638
|
|
|
|
,-15617,-15572,-15556,-15515,-15489,-15461,-15424,-15400,-15365,-15338,-15304
|
|
|
|
,-15281,-15241,15212,15189,15155,15125,15098,15064,15038,15005,14977
|
|
|
|
,14947,14918,14886,14859,14827,14799,14771,14738,14711,14681,14651
|
|
|
|
,14623,14592,14565,14532,14508,14474,14449,14416,14391,14357,14334
|
|
|
|
,14301,14273,14246,14214,14188,14159,14128,14104,14069,14046,14016
|
|
|
|
,13986,13958,-13928,-13905,-13869,-13849,-13816,-13789,-13758,-13736,-13702
|
|
|
|
,-13678,-13649,-13616,-13598,-13561,-13539,-13508,-13480,-13455,-13424,-13399
|
|
|
|
,-13371,-13341,-13318,-13284,-13263,-13232,-13205,-13179,-13150,-13124,-13096
|
|
|
|
,-13069,-13041,-13017,-12984,-12965,-12930,-12908,-12881,-12849,-12831,-12793
|
|
|
|
,-12779,-12739,12714,12694,12666,12636,12616,12583,12561,12531,12509
|
|
|
|
,12476,12459,12421,12406,12373,12347,12325,12294,12271,12244,12218
|
|
|
|
,12194,12164,12142,12112,12091,12062,12038,12009,11989,11956,11939
|
|
|
|
,11903,11888,11855,11834,11806,11782,11755,11732,11705,11679,11658
|
|
|
|
,11628,11605,-11579,-11557,-11527,-11505,-11480,-11455,-11429,-11406,-11380
|
|
|
|
,-11355,-11331,-11305,-11283,-11256,-11231,-11210,-11178,-11166,-11126,-11117
|
|
|
|
,-11080,-11063,-11037,-11010,-10992,-10961,-10940,-10916,-10890,-10871,-10838
|
|
|
|
,-10825,-10791,-10774,-10747,-10724,-10699,-10679,-10648,-10634,-10600,-10586
|
|
|
|
,-10554,-10537,10513,10485,10466,10438,10420,10391,10370,10349,10321
|
|
|
|
,10305,10273,10257,10228,10211,10183,10164,10138,10115,10096,10066
|
|
|
|
,10053,10019,10007,9975,9960,9930,9916,9883,9871,9839,9823
|
|
|
|
,9801,9771,9759,9726,9714,9684,9666,9640,9623,9596,9577
|
|
|
|
,9553,9532,-9510,-9487,-9467,-9443,-9422,-9401,-9377,-9358,-9334
|
|
|
|
,-9313,-9292,-9270,-9248,-9227,-9205,-9182,-9165,-9138,-9121,-9098
|
|
|
|
,-9075,-9057,-9032,-9015,-8989,-8973,-8947,-8929,-8907,-8885,-8867
|
|
|
|
,-8842,-8824,-8802,-8780,-8763,-8737,-8720,-8699,-8676,-8657,-8637
|
|
|
|
,-8614,-8597,8576,8554,8532,8513,8494,8470,8454,8429,8413
|
|
|
|
,8390,8371,8351,8328,8314,8286,8274,8247,8233,8207,8192
|
|
|
|
,8170,8149,8134,8108,8092,8070,8053,8031,8014,7991,7974
|
|
|
|
,7953,7935,7912,7899,7872,7861,7832,7820,7798,7779,7761
|
|
|
|
,7739,7724,-7706,-7679,-7669,-7641,-7628,-7607,-7588,-7570,-7551
|
|
|
|
,-7530,-7515,-7491,-7478,-7456,-7438,-7419,-7401,-7379,-7369,-7338
|
|
|
|
,-7335,-7300,-7295,-7267,-7255,-7233,-7218,-7196,-7181,-7159,-7145
|
|
|
|
,-7124,-7107,-7090,-7068,-7055,-7033,-7018,-6999,-6979,-6966,-6942
|
|
|
|
,-6929,-6909,6891,6875,6855,6840,6820,6803,6787,6768,6750
|
|
|
|
,6733,6717,6695,6687,6657,6650,6629,6608,6599,6573,6562
|
|
|
|
,6543,6525,6508,6494,6470,6462,6437,6426,6405,6391,6371
|
|
|
|
,6358,6338,6323,6305,6289,6273,6254,6241,6221,6206,6191
|
|
|
|
,6170,6160,6136,-6121,-6108,-6090,-6075,-6057,-6044,-6023,-6013
|
|
|
|
,-5988,-5983,-5955,-5950,-5926,-5914,-5897,-5879,-5867,-5846,-5837
|
|
|
|
,-5813,-5806,-5780,-5774,-5751,-5741,-5720,-5710,-5687,-5680,-5656
|
|
|
|
,-5648,-5626,-5616,-5596,-5584,-5566,-5552,-5538,-5519,-5507,-5490
|
|
|
|
,-5475,-5463,-5440,5425,5419,5396,5385,5373,5350,5342,5324
|
|
|
|
,5308,5297,5278,5266,5250,5236,5218,5209,5190,5176,5162
|
|
|
|
,5148,5131,5120,5103,5088,5075,5061,5043,5035,5013,5005
|
|
|
|
,4988,4973,4960,4946,4931,4916,4905,4885,4879,4856,4850
|
|
|
|
,4829,4823,4799,-4785,-4783,-4758,-4749,-4738,-4718,-4710,-4693
|
|
|
|
,-4679,-4669,-4649,-4643,-4621,-4616,-4596,-4585,-4572,-4555,-4548
|
|
|
|
,-4527,-4521,-4501,-4492,-4477,-4464,-4451,-4437,-4425,-4410,-4399
|
|
|
|
,-4384,-4372,-4359,-4345,-4332,-4320,-4307,-4292,-4283,-4265,-4256
|
|
|
|
,-4243,-4227,-4217,4201,4196,4171,4173,4145,4147,4123,4117
|
|
|
|
,4103,4087,4079,4065,4051,4042,4026,4014,4005,3988,3981
|
|
|
|
,3962,3956,3939,3931,3917,3903,3892,3882,3866,3860,3841
|
|
|
|
,3831,3824,3804,3800,3782,3772,3761,3749,3737,3726,3712
|
|
|
|
,3702,3690,3679,-3667,-3656,-3640,-3637,-3614,-3614,-3594,-3587
|
|
|
|
,-3573,-3564,-3549,-3542,-3528,-3517,-3506,-3494,-3482,-3475,-3458
|
|
|
|
,-3452,-3437,-3427,-3417,-3406,-3392,-3384,-3372,-3359,-3354,-3335
|
|
|
|
,-3330,-3316,-3306,-3297,-3283,-3276,-3259,-3256,-3239,-3232,-3220
|
|
|
|
,-3210,-3196,-3192,3182,3161,3161,3143,3137,3124,3114,3103
|
|
|
|
,3096,3080,3075,3060,3054,3040,3034,3018,3013,2999,2992
|
|
|
|
,2980,2971,2958,2953,2937,2933,2918,2910,2901,2889,2881
|
|
|
|
,2869,2862,2849,2842,2828,2824,2810,2801,2793,2780,2774
|
|
|
|
,2762,2755,2740,-2730,-2729,-2711,-2706,-2697,-2683,-2681,-2665
|
|
|
|
,-2658,-2650,-2636,-2633,-2618,-2614,-2599,-2593,-2585,-2571,-2568
|
|
|
|
,-2556,-2542,-2544,-2521,-2526,-2507,-2502,-2492,-2483,-2474,-2467
|
|
|
|
,-2455,-2447,-2440,-2428,-2422,-2412,-2402,-2396,-2385,-2376,-2369
|
|
|
|
,-2359,-2351,-2344,2336,2323,2319,2303,2306,2282,2290,2269
|
|
|
|
,2268,2254,2251,2238,2234,2221,2217,2203,2203,2187,2184
|
|
|
|
,2171,2168,2155,2150,2141,2132,2125,2116,2109,2099,2094
|
|
|
|
,2083,2078,2066,2062,2052,2045,2037,2027,2023,2011,2009
|
|
|
|
,1994,1992,1980,-1973,-1967,-1959,-1950,-1945,-1937,-1926,-1923
|
|
|
|
,-1911,-1907,-1899,-1889,-1885,-1873,-1871,-1860,-1853,-1847,-1838
|
|
|
|
,-1832,-1824,-1816,-1811,-1801,-1795,-1789,-1778,-1776,-1765,-1759
|
|
|
|
,-1753,-1742,-1742,-1726,-1728,-1714,-1710,-1703,-1696,-1688,-1682
|
|
|
|
,-1676,-1664,-1667,1661,1641,1645,1632,1625,1625,1607,1612
|
|
|
|
,1596,1596,1585,1581,1570,1571,1556,1556,1546,1539,1536
|
|
|
|
,1525,1523,1512,1511,1497,1499,1487,1481,1480,1465,1466
|
|
|
|
,1455,1450,1447,1436,1434,1423,1420,1414,1407,1401,1395
|
|
|
|
,1388,1382,1379,1369,-1364,-1359,-1352,-1348,-1338,-1336,-1328
|
|
|
|
,-1322,-1318,-1310,-1305,-1300,-1291,-1290,-1280,-1277,-1269,-1267
|
|
|
|
,-1256,-1255,-1246,-1242,-1238,-1228,-1225,-1221,-1212,-1209,-1203
|
|
|
|
,-1195,-1193,-1186,-1180,-1175,-1170,-1163,-1161,-1150,-1150,-1142
|
|
|
|
,-1137,-1133,-1126,-1119,1113,1112,1105,1100,1096,1089,1084
|
|
|
|
,1080,1075,1068,1067,1054,1059,1045,1045,1041,1031,1031
|
|
|
|
,1022,1018,1016,1007,1006,997,996,987,986,979,975
|
|
|
|
,970,966,959,957,949,948,940,939,928,932,920
|
|
|
|
,918,915,907,906,-900,-896,-890,-885,-883,-877,-871
|
|
|
|
,-870,-862,-860,-856,-848,-848,-841,-837,-834,-827,-827
|
|
|
|
,-817,-817,-811,-808,-803,-798,-794,-791,-786,-783,-777
|
|
|
|
,-774,-769,-765,-763,-756,-754,-748,-746,-741,-737,-732
|
|
|
|
,-731,-722,-727,-710,707,714,704,700,702,690,693
|
|
|
|
,684,685,676,677,671,665,668,656,657,653,649
|
|
|
|
,644,645,632,640,626,631,620,623,614,615,607
|
|
|
|
,608,601,598,598,588,592,582,584,576,577,568
|
|
|
|
,571,564,561,558,-554,-553,-546,-546,-541,-540,-532
|
|
|
|
,-537,-522,-531,-519,-521,-515,-513,-510,-505,-507,-495
|
|
|
|
,-503,-489,-495,-486,-486,-481,-480,-476,-472,-472,-465
|
|
|
|
,-467,-458,-461,-453,-455,-450,-444,-446,-439,-441,-433
|
|
|
|
,-435,-428,-428,-425,424,416,417,413,411,407,407
|
|
|
|
,401,400,397,396,389,394,381,388,379,381,375
|
|
|
|
,376,368,371,365,365,360,360,356,353,353,347
|
|
|
|
,347,346,340,339,339,331,337,326,330,323,325
|
|
|
|
,319,321,312,318,-316,-305,-310,-303,-303,-302,-296
|
|
|
|
,-298,-292,-293,-289,-288,-285,-283,-281,-279,-278,-274
|
|
|
|
,-273,-269,-271,-265,-265,-264,-257,-262,-255,-254,-255
|
|
|
|
,-248,-250,-247,-243,-247,-236,-244,-232,-240,-231,-232
|
|
|
|
,-232,-223,-232,-220,219,224,217,218,216,212,212
|
|
|
|
,212,207,208,204,202,204,200,197,197,195,193
|
|
|
|
,194,187,191,186,184,187,177,186,175,180,175
|
|
|
|
,173,175,169,172,168,165,167,162,166,157,162
|
|
|
|
,156,158,156,152,-152,-151,-149,-149,-146,-147,-142
|
|
|
|
,-145,-140,-141,-138,-137,-139,-131,-138,-128,-135,-126
|
|
|
|
,-132,-124,-129,-123,-125,-121,-123,-116,-123,-116,-117
|
|
|
|
,-115,-113,-114,-112,-112,-107,-110,-108,-104,-109,-100
|
|
|
|
,-105,-103,-99,-101,99,99,94,98,93,96,89
|
|
|
|
,96,87,91,88,89,86,88,81,86,83,82
|
|
|
|
,82,78,83,73,83,73,77,76,72,74,73
|
|
|
|
,69,73,70,67,71,63,71,62,69,59,68
|
|
|
|
,58,66,58,63,57,-58,-58,-57,-56,-56,-55
|
|
|
|
,-56,-51,-57,-47,-56,-48,-53,-49,-48,-50,-45
|
|
|
|
,-50,-45,-46,-46,-43,-45,-43,-43,-41,-43,-39
|
|
|
|
,-43,-37,-42,-35,-42,-34,-39,-36,-36,-35,-35
|
|
|
|
,-34,-34,-34,-31,-35,35,28,34,27,35,23
|
|
|
|
,35,23,32,26,27,28,24,28,23,27,24
|
|
|
|
,24,25,21,25,22,22,23,19,23,20,20
|
|
|
|
,22,16,23,15,23,13,23,12,23,13,18
|
|
|
|
,16,15,16,16,14,-14,-14,-16,-11,-18,-9
|
|
|
|
,-17,-8,-17,-10,-14,-10,-11,-13,-10,-12,-9
|
|
|
|
,-10,-11,-9,-11,-8,-9,-10,-6,-13,-4,-12
|
|
|
|
,-4,-12,-2,-14,-1,-12,-3,-8,-6,-7,-6
|
|
|
|
,-6,-5,-6,-5,-6,6,3,8,2,7,2
|
|
|
|
,7,2,6,1,6,4,1,9,-5,12,-5
|
|
|
|
,10,-1,5,0,5,1,5,0,3,3,1
|
|
|
|
,3,2,1,3,0,5,-2,4,0,2,3
|
|
|
|
,-1,4,-3,6,-3,2,-2,-2,0,-1,-2
|
|
|
|
,1,-1,-2,1,-2,0,0,-2,2,-3,2
|
|
|
|
,-4,4,-5,5,-5,2,0,-1,0,1,-4
|
|
|
|
,5,-5,4,-3,2,-1,-1,1,-2,2,-2
|
|
|
|
,2,-2,2,-1,0,1,-1,0,1,-2,3
|
|
|
|
,-3,2,-1,0,1,-1,0,0,1,-1,1
|
|
|
|
,-2,3
|
|
|
|
};
|
|
|
|
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
Utilities from pdbox plugin (Copyright (C) 2009 Wincent Balin) --- am I
|
|
|
|
supposed to supply these functions with the plugin? Should I use a library?
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
|
|
|
/* Implementation of strtod() and atof(),
|
|
|
|
taken from SanOS (http://www.jbox.dk/sanos/). */
|
|
|
|
static int rb_errno = 0;
|
|
|
|
|
|
|
|
static double rb_strtod(const char *str, char **endptr)
|
|
|
|
{
|
|
|
|
double number;
|
|
|
|
int exponent;
|
|
|
|
int negative;
|
|
|
|
char *p = (char *) str;
|
|
|
|
double p10;
|
|
|
|
int n;
|
|
|
|
int num_digits;
|
|
|
|
int num_decimals;
|
|
|
|
|
|
|
|
/* Reset Rockbox errno -- W.B. */
|
|
|
|
#ifdef ROCKBOX
|
|
|
|
rb_errno = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Skip leading whitespace
|
|
|
|
while (isspace(*p)) p++;
|
|
|
|
|
|
|
|
// Handle optional sign
|
|
|
|
negative = 0;
|
|
|
|
switch (*p)
|
|
|
|
{
|
|
|
|
case '-': negative = 1; // Fall through to increment position
|
|
|
|
case '+': p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
number = 0.;
|
|
|
|
exponent = 0;
|
|
|
|
num_digits = 0;
|
|
|
|
num_decimals = 0;
|
|
|
|
|
|
|
|
// Process string of digits
|
|
|
|
while (isdigit(*p))
|
|
|
|
{
|
|
|
|
number = number * 10. + (*p - '0');
|
|
|
|
p++;
|
|
|
|
num_digits++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process decimal part
|
|
|
|
if (*p == '.')
|
|
|
|
{
|
|
|
|
p++;
|
|
|
|
|
|
|
|
while (isdigit(*p))
|
|
|
|
{
|
|
|
|
number = number * 10. + (*p - '0');
|
|
|
|
p++;
|
|
|
|
num_digits++;
|
|
|
|
num_decimals++;
|
|
|
|
}
|
|
|
|
|
|
|
|
exponent -= num_decimals;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num_digits == 0)
|
|
|
|
{
|
|
|
|
#ifdef ROCKBOX
|
|
|
|
rb_errno = 1;
|
|
|
|
#else
|
|
|
|
errno = ERANGE;
|
|
|
|
#endif
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Correct for sign
|
|
|
|
if (negative) number = -number;
|
|
|
|
|
|
|
|
// Process an exponent string
|
|
|
|
if (*p == 'e' || *p == 'E')
|
|
|
|
{
|
|
|
|
// Handle optional sign
|
|
|
|
negative = 0;
|
|
|
|
switch(*++p)
|
|
|
|
{
|
|
|
|
case '-': negative = 1; // Fall through to increment pos
|
|
|
|
case '+': p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process string of digits
|
|
|
|
n = 0;
|
|
|
|
while (isdigit(*p))
|
|
|
|
{
|
|
|
|
n = n * 10 + (*p - '0');
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (negative)
|
|
|
|
exponent -= n;
|
|
|
|
else
|
|
|
|
exponent += n;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef ROCKBOX
|
|
|
|
if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP)
|
|
|
|
{
|
|
|
|
errno = ERANGE;
|
|
|
|
return HUGE_VAL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Scale the result
|
|
|
|
p10 = 10.;
|
|
|
|
n = exponent;
|
|
|
|
if (n < 0) n = -n;
|
|
|
|
while (n)
|
|
|
|
{
|
|
|
|
if (n & 1)
|
|
|
|
{
|
|
|
|
if (exponent < 0)
|
|
|
|
number /= p10;
|
|
|
|
else
|
|
|
|
number *= p10;
|
|
|
|
}
|
|
|
|
n >>= 1;
|
|
|
|
p10 *= p10;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef ROCKBOX
|
|
|
|
if (number == HUGE_VAL) errno = ERANGE;
|
|
|
|
#endif
|
|
|
|
if (endptr) *endptr = p;
|
|
|
|
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
|
|
|
|
static double rb_atof(const char *str)
|
|
|
|
{
|
|
|
|
return rb_strtod(str, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
Actual metronome stuff
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
|
|
|
static int fd = -1; /* file descriptor, global for cleanup(). */
|
|
|
|
|
|
|
|
/* Round fixed-point number to integer. */
|
|
|
|
static int fp_rint(long fp_num)
|
|
|
|
{
|
|
|
|
fp_num += fp_num > 0 ? +((long)1<<15) : -((long)1<<15);
|
|
|
|
return (int)(fp_num / ((long)1<<16));
|
|
|
|
}
|
|
|
|
/* float to fixed-point */
|
|
|
|
static long fp_frac(float fl_num)
|
|
|
|
{
|
|
|
|
return (long)(fl_num*((long)1<<16));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* simple dynamic memory management
|
|
|
|
- only allocate blocks serially
|
|
|
|
- deallocation of most recent blocks by resetting the free region pointer
|
|
|
|
- everything aligned to 4 bytes (wasting some bytes, but playing safe)
|
|
|
|
*/
|
|
|
|
static void *mem_begin = NULL; /* beginning of managed region. */
|
|
|
|
static void *mem_end = NULL; /* just after end of managed region */
|
|
|
|
static void *mem_free_region = NULL; /* pointer to unused free space */
|
|
|
|
static void *mem_checkpointer = NULL; /* position to reset to */
|
|
|
|
|
|
|
|
/* Initialize memory management. */
|
|
|
|
static void mem_init(void)
|
|
|
|
{
|
|
|
|
size_t bufsize;
|
|
|
|
/* Can I trust that pointer to be aligned? Better be safe. */
|
|
|
|
mem_begin = ALIGN_UP(rb->plugin_get_buffer(&bufsize), 4);
|
|
|
|
mem_end = mem_begin + bufsize - 3;
|
|
|
|
mem_free_region = mem_begin;
|
|
|
|
mem_checkpointer = mem_begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remember and reset free region, for temporary mem usage. */
|
|
|
|
static void mem_checkpoint(void){ mem_checkpointer = mem_free_region; }
|
|
|
|
static void mem_reset (void){ mem_free_region = mem_checkpointer; }
|
|
|
|
static void *mem_allocate(size_t bytes)
|
|
|
|
{
|
|
|
|
void *handout = mem_free_region;
|
|
|
|
/* Always handing out multiples of alignment size. */
|
|
|
|
if(bytes % 4) bytes += 4 - bytes % 4;
|
|
|
|
if(mem_free_region + bytes >= mem_end)
|
|
|
|
{
|
|
|
|
rb->splash(2*HZ, "Out Of Memory");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
mem_free_region += bytes;
|
|
|
|
return handout;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct part;
|
|
|
|
struct part /* One part of a track, with one tempo (range), meter, etc. */
|
|
|
|
{
|
|
|
|
struct part *prev, *next; /* linked list links*/
|
|
|
|
unsigned int id; /* index (in order, please) */
|
|
|
|
char *label;
|
|
|
|
unsigned int bars; /* Duration of part in bars. */
|
|
|
|
unsigned int beats_per_bar; /* 3 in 3/4 */
|
|
|
|
unsigned int base_beat; /* 4 in 3/4 to adjust bpm value */
|
|
|
|
unsigned int bpm; /* base tempo (1/4 notes per minute) */
|
|
|
|
unsigned int bpm2; /* end tempo */
|
|
|
|
unsigned int *beat_bpm; /* either NULL or (bars*beats_per_bar) values */
|
|
|
|
long accel; /* fixed-point acceleration in 1/min (really) */
|
|
|
|
int volume; /* volume offset in integer dB */
|
|
|
|
/* Store pattern characters verbatim for max. 64 beats (no string
|
|
|
|
termination). One could save storage here by encoding things in bits,
|
|
|
|
or by allocating dynamically to begin with. */
|
|
|
|
char *pattern;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct part *part_list = NULL; /* linked list of parts */
|
|
|
|
static struct part *part = NULL; /* current part */
|
|
|
|
static unsigned int parts = 0; /* total number of parts */
|
|
|
|
static unsigned int bad_parts = 0; /* Count parts with parsing errors. */
|
|
|
|
|
|
|
|
/* Initialize a part that is not yet placed into the list. */
|
|
|
|
static void part_init(struct part *ps)
|
|
|
|
{
|
|
|
|
ps->prev = NULL;
|
|
|
|
ps->next = NULL;
|
|
|
|
ps->id = 0;
|
|
|
|
ps->label = NULL;
|
|
|
|
ps->bars = 0;
|
|
|
|
ps->beats_per_bar = 4;
|
|
|
|
ps->base_beat = 4;
|
|
|
|
ps->bpm = 120;
|
|
|
|
ps->bpm2 = 120;
|
|
|
|
ps->beat_bpm = NULL;
|
|
|
|
ps->accel = 0;
|
|
|
|
ps->volume = 0;
|
|
|
|
ps->pattern = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add to the list. */
|
|
|
|
static void part_add(struct part *ps)
|
|
|
|
{
|
|
|
|
if(part)
|
|
|
|
{
|
|
|
|
part->next = ps;
|
|
|
|
ps->prev = part;
|
|
|
|
part = ps;
|
|
|
|
}
|
|
|
|
else part = part_list = ps;
|
|
|
|
|
|
|
|
ps->id = parts++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Stay away from zero. */
|
|
|
|
static unsigned int positive(long long value)
|
|
|
|
{
|
|
|
|
return value > 0 ? value : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Yay! Global state variables! */
|
|
|
|
static bool track_mode = false; /* switch for programmed tracks metronome */
|
|
|
|
static int loop = 0; /* Needed? */
|
|
|
|
static unsigned int beat = 0;
|
|
|
|
static unsigned int bar = 0; /* How big shall this become? */
|
|
|
|
/* The currently (approximate) active bpm value, set from calc_period(). */
|
|
|
|
static unsigned int bpm = 1;
|
|
|
|
|
|
|
|
/* Should be unsigned? */
|
|
|
|
static unsigned int period = 0; /* beat interval in timer ticks */
|
|
|
|
static long period_diff = 0; /* fixed-point error of last period computation */
|
|
|
|
static unsigned int minitick = 0; /* elapsed ticks */
|
|
|
|
static bool beating = false; /* A beat is/was playing and count needs to increase. */
|
|
|
|
static int display_state = 0; /* Current display state code. */
|
|
|
|
static bool display_trigger = false; /* Draw display on next occasion */
|
2004-03-12 08:21:26 +00:00
|
|
|
|
|
|
|
static bool sound_active = false;
|
|
|
|
static bool sound_paused = true;
|
2004-03-17 14:54:32 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* global static buffer for messages in any situation */
|
|
|
|
static char buffer[64];
|
|
|
|
/* For line parsing, more is needed, allocated on demand.
|
|
|
|
As my memory management doesn't allow to free it, keeping it local
|
|
|
|
ist not smart. */
|
|
|
|
static char* linebuf = NULL;
|
|
|
|
size_t linebuf_size = 0;
|
2004-03-12 08:21:26 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
|
|
|
|
/* global state for tempo tapping */
|
2007-07-29 05:30:04 +00:00
|
|
|
static bool reset_tap = false;
|
2004-11-26 13:31:40 +00:00
|
|
|
static int tap_count = 0;
|
|
|
|
static int tap_time = 0;
|
|
|
|
static int tap_timeout = 0;
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
static int bpm_step_counter = 0;
|
|
|
|
|
|
|
|
static bool sound_trigger = false;
|
2006-01-14 02:39:30 +00:00
|
|
|
|
2006-01-10 02:51:50 +00:00
|
|
|
#define MET_IS_PLAYING rb->pcm_is_playing()
|
2006-01-14 02:39:30 +00:00
|
|
|
#define MET_PLAY_STOP rb->audio_stop()
|
2006-01-10 02:51:50 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* Really necessary? Cannot just play mono?
|
|
|
|
Also: This is wasted memory! */
|
|
|
|
static short tick_buf[sizeof(tick_sound)*2];
|
|
|
|
static short tock_buf[sizeof(tock_sound)*2];
|
2006-01-10 02:51:50 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* Convert the mono samples to interleaved stereo */
|
|
|
|
static void prepare_buffers(void)
|
2006-01-10 22:22:19 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
size_t i;
|
|
|
|
for(i = 0;i < sizeof(tick_sound)/sizeof(short);i++)
|
|
|
|
tick_buf[i*2] = tick_buf[i*2+1] = tick_sound[i];
|
|
|
|
for(i = 0;i < sizeof(tock_sound)/sizeof(short);i++)
|
|
|
|
tock_buf[i*2] = tock_buf[i*2+1] = tock_sound[i];
|
2006-01-10 22:22:19 +00:00
|
|
|
}
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
static void play_tick(void)
|
2008-11-25 13:48:40 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
rb->pcm_play_data(NULL, NULL, tick_buf, sizeof(tick_buf));
|
2006-01-10 02:51:50 +00:00
|
|
|
}
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
static void play_tock(void)
|
2006-01-10 02:51:50 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
rb->pcm_play_data(NULL, NULL, tock_buf, sizeof(tock_buf));
|
2006-01-10 02:51:50 +00:00
|
|
|
}
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* State: 0: blank/title, 1: tick, 2: tock 3: silent klick */
|
|
|
|
/* TODO: Could use more smart placement, using
|
|
|
|
lcd_getstringsize() and such. */
|
|
|
|
static void metronome_draw(struct screen* display, int state)
|
2006-01-10 02:51:50 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
struct part *ps;
|
|
|
|
int textlen = display->lcdwidth / display->getcharwidth();
|
|
|
|
ps = part;
|
2007-07-29 03:43:37 +00:00
|
|
|
display->clear_display();
|
|
|
|
display->setfont(FONT_SYSFIXED);
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
switch(state)
|
2007-07-29 03:43:37 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
case 0:
|
|
|
|
if(sound_paused)
|
|
|
|
{
|
|
|
|
if(track_mode) display->puts(0, 0, "Metronome Track");
|
|
|
|
else display->puts(0, 0, "Metronome");
|
|
|
|
|
|
|
|
display->hline(0, display->lcdwidth, 12);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
/* Draw odd/even ticks/tocks differently to be able to go without
|
|
|
|
display clearing in between for fast beats. */
|
|
|
|
case 1:
|
|
|
|
if((beat+1) % 2 == 0)
|
|
|
|
display->fillrect( display->lcdwidth/2, 0
|
|
|
|
, display->lcdwidth, 12 );
|
|
|
|
else
|
|
|
|
display->fillrect( 0, 0
|
|
|
|
, display->lcdwidth/2-1, 12 );
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if((beat+1) % 2 == 0)
|
|
|
|
display->fillrect( display->lcdwidth/2, display->lcdheight-13
|
|
|
|
, display->lcdwidth, 12 );
|
|
|
|
else
|
|
|
|
display->fillrect( 0, display->lcdheight-13
|
|
|
|
, display->lcdwidth/2-1, 12 );
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
display->puts((textlen-3)/2,0, "o.O");
|
|
|
|
break;
|
2007-07-29 03:43:37 +00:00
|
|
|
}
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
|
|
|
|
if(track_mode)
|
2007-07-29 03:43:37 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
|
|
|
|
/* One line in several. */
|
|
|
|
rb->snprintf( buffer, sizeof(buffer), "%u/%u@%u V%d"
|
|
|
|
, ps->beats_per_bar, ps->base_beat
|
|
|
|
, bpm, rb->global_settings->volume );
|
|
|
|
display->puts(0,4, buffer);
|
2020-07-17 14:31:31 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* Would it hurt to draw a 3rd line to 2-line display?
|
|
|
|
I guess there are 3-line displays out there. */
|
|
|
|
if(ps->label && rb->strlen(ps->label))
|
|
|
|
{
|
|
|
|
rb->snprintf(buffer, sizeof(buffer), "\"%s\"", ps->label);
|
|
|
|
display->puts((textlen-rb->strlen(buffer))/2, 2, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Wildly guessing here with puts(). */
|
|
|
|
if(ps->bars)
|
|
|
|
rb->snprintf( buffer, sizeof(buffer), "P%u/%u: B%u/%u+%u"
|
|
|
|
, part->id+1, parts, bar+1, ps->bars, beat+1 );
|
|
|
|
else
|
|
|
|
rb->snprintf( buffer, sizeof(buffer), "P%u/%u: B%u/_+%u"
|
|
|
|
, part->id+1, parts, bar+1, beat+1 );
|
|
|
|
display->puts(0, 5, buffer);
|
|
|
|
|
2007-07-29 03:43:37 +00:00
|
|
|
}
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
else /* track mode */
|
|
|
|
{
|
|
|
|
|
|
|
|
if(display->screen_type==SCREEN_MAIN)
|
|
|
|
{
|
|
|
|
#ifdef MET_SYNC
|
|
|
|
display->puts(0, 5, "Select=TAP Rec=SYNC");
|
|
|
|
#else
|
|
|
|
display->puts(0, 5, "Select=TAP");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifdef HAVE_REMOTE_LCD
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef MET_SYNC
|
|
|
|
display->puts(0, 5, "Rec=TAP Mode=SYNC");
|
|
|
|
#else
|
|
|
|
display->puts(0, 5, "Rec=TAP");
|
|
|
|
#endif
|
|
|
|
}
|
2007-07-29 03:43:37 +00:00
|
|
|
#endif
|
2004-03-17 14:54:32 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
rb->snprintf( buffer, sizeof(buffer), "BPM: %d Vol: %d"
|
|
|
|
, bpm, rb->global_settings->volume );
|
|
|
|
display->puts(0,3, buffer);
|
2020-07-17 14:31:31 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
display->hline(0, 111, 12);
|
|
|
|
if(sound_paused) display->puts(0,2,"start: hold select");
|
|
|
|
else display->puts(0,2,"stop : cancel");
|
2004-03-12 08:21:26 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
} /* !track_mode */
|
|
|
|
|
2008-03-09 02:36:17 +00:00
|
|
|
display->setfont(FONT_UI);
|
2007-07-29 03:43:37 +00:00
|
|
|
display->update();
|
2004-03-12 08:21:26 +00:00
|
|
|
}
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* Trigger drawing of display at the next occasion using given state. */
|
|
|
|
static void trigger_display(int state)
|
|
|
|
{
|
|
|
|
display_state = state;
|
|
|
|
display_trigger = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Actually draw display. */
|
2011-10-04 19:33:52 +00:00
|
|
|
static void draw_display(void)
|
2007-07-29 03:43:37 +00:00
|
|
|
{
|
|
|
|
FOR_NB_SCREENS(i)
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
metronome_draw(rb->screens[i], display_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Modify actual volume by given offset without changing the configured one.
|
|
|
|
This is for parts with associated volume. */
|
|
|
|
static void tweak_volume(int offset)
|
|
|
|
{
|
|
|
|
int vol = rb->global_settings->volume + offset;
|
|
|
|
int minvol = rb->sound_min(SOUND_VOLUME);
|
|
|
|
int maxvol = rb->sound_max(SOUND_VOLUME);
|
|
|
|
|
|
|
|
if (vol > maxvol) vol = maxvol;
|
|
|
|
else if(vol < minvol) vol = minvol;
|
|
|
|
|
|
|
|
rb->sound_set(SOUND_VOLUME, vol);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* tempo at a certain point in beat space in an accelerated part */
|
|
|
|
static long accel_tempo(struct part *ps, long offset)
|
|
|
|
{
|
|
|
|
long fp_bpm = (long)ps->bpm<<16;
|
|
|
|
long fp_bpm2 = (long)ps->bpm2<<16;
|
|
|
|
long v = fp_bpm + fp_mul(ps->accel, offset, 16);
|
|
|
|
/* Offset could be negative, actually, so ensure tempo stays within both
|
|
|
|
bounds */
|
|
|
|
if(ps->accel > 0)
|
|
|
|
{
|
|
|
|
if(v < fp_bpm) v = fp_bpm;
|
|
|
|
if(v > fp_bpm2) v = fp_bpm2;
|
|
|
|
}
|
|
|
|
else /* deceleration */
|
|
|
|
{
|
|
|
|
if(v > fp_bpm) v = fp_bpm;
|
|
|
|
if(v < fp_bpm2) v = fp_bpm2;
|
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate number of ticks to wait till next beat. */
|
|
|
|
static void calc_period(void)
|
|
|
|
{
|
|
|
|
struct part *ps = part;
|
|
|
|
long deltat;
|
|
|
|
long beatlen; /* in quarter notes */
|
|
|
|
long period_fp;
|
|
|
|
|
|
|
|
beatlen = fp_div(4<<16, ps->base_beat<<16, 16);
|
|
|
|
/* Hack: Put the factor 60 in before computing deltat, to preserve
|
|
|
|
some accuracty. */
|
|
|
|
if(ps->beat_bpm)
|
|
|
|
{
|
|
|
|
bpm = ps->beat_bpm[bar*ps->beats_per_bar+beat];
|
|
|
|
deltat = fp_div(fp_mul(60<<16,beatlen,16), bpm<<16, 16);
|
|
|
|
} else
|
|
|
|
if(ps->accel == 0.f)
|
|
|
|
{ /* Fixed tempo. */
|
|
|
|
bpm = ps->bpm;
|
|
|
|
/* Minutes per base beat, from quarters per minute. */
|
|
|
|
deltat = fp_div(fp_mul(60<<16,beatlen,16), bpm<<16, 16);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* Acceleration, varying period with each beat. */
|
|
|
|
long v0, v1;
|
|
|
|
long offset = (bar*ps->beats_per_bar + beat) << 16;
|
|
|
|
/* Always computed from start of part for seeking and accuracy. */
|
|
|
|
v0 = accel_tempo(ps, fp_mul(beatlen, offset, 16));
|
|
|
|
offset += 1<<16;
|
|
|
|
v1 = accel_tempo(ps, fp_mul(beatlen, offset, 16));
|
|
|
|
/* Playing safe with too small tempo changes, avoiding the acceleration
|
|
|
|
math that might divide by very small deltat. */
|
|
|
|
if(labs(v1-v0) > 1<<8)
|
|
|
|
{
|
|
|
|
/* deltat = 1.f / ps->accel * rb_log(v1/v0) */
|
|
|
|
deltat = fp_mul( fp_div(60<<16, ps->accel, 16)
|
|
|
|
, fp16_log(fp_div(v1, v0, 16))
|
|
|
|
, 16 );
|
|
|
|
bpm = fp_rint(fp_div(fp_mul(60<<16, beatlen, 16), deltat, 16));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* Arbitrarily choosing v1. */
|
|
|
|
bpm = fp_rint(v1);
|
|
|
|
deltat = fp_div(fp_mul(60<<16,beatlen,16), v1, 16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* The treatment of the rounding error when converting to integer
|
|
|
|
period using period_diff helps a lot to keep track lengths close to
|
|
|
|
"correct" even with timerfreq_div as low as 77. Actually, I have _less_
|
|
|
|
drift than with timerfreq_div of 1000! */
|
|
|
|
period_fp = fp_mul(timerfreq_div<<16, deltat, 16) + period_diff;
|
|
|
|
period = positive(fp_rint( period_fp ));
|
|
|
|
period_diff = period_fp - (long)(period<<16);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Last beat finished, to prepare for the next one. */
|
|
|
|
static void advance_beat(void)
|
|
|
|
{
|
|
|
|
if(++beat == part->beats_per_bar)
|
|
|
|
{
|
|
|
|
beat = 0;
|
|
|
|
/* Bar counter always incremented for acceleration, but only checked
|
|
|
|
against a limit if there is one. */
|
|
|
|
++bar;
|
|
|
|
if(part->bars && bar == part->bars)
|
|
|
|
{
|
|
|
|
bar = 0;
|
|
|
|
if(part->next) part = part->next;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
part = part_list;
|
|
|
|
if(!loop) sound_paused = true;
|
|
|
|
}
|
|
|
|
tweak_volume(part->volume);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Always recompute period, as acceleration changes it for each beat. */
|
|
|
|
calc_period();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Decide what to play, update display, play it.
|
|
|
|
Beat counting happens here, too. */
|
|
|
|
static void play_ticktock(void)
|
|
|
|
{
|
|
|
|
if(beating) advance_beat();
|
|
|
|
|
|
|
|
/* Hack: Clear trigger to avoid race condition. */
|
|
|
|
display_trigger = 0;
|
|
|
|
if(sound_paused)
|
|
|
|
{
|
|
|
|
beating = false;
|
|
|
|
display_state = 0;
|
|
|
|
draw_display();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char pat = 'x';
|
|
|
|
if(part->pattern) pat = part->pattern[beat];
|
|
|
|
|
|
|
|
beating = true;
|
|
|
|
/* Blinking and specific sound for tick, tock and silent beat.
|
|
|
|
Drawing display first for slow machines (YH820), to avoid
|
|
|
|
interrupting audio for regular playback. */
|
|
|
|
switch(pat)
|
|
|
|
{
|
|
|
|
case 'X':
|
|
|
|
display_state = 1;
|
|
|
|
draw_display();
|
|
|
|
play_tick();
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
display_state = 2;
|
|
|
|
draw_display();
|
|
|
|
play_tock();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
display_state = 3;
|
|
|
|
draw_display();
|
|
|
|
}
|
|
|
|
}
|
2007-07-29 03:43:37 +00:00
|
|
|
}
|
2007-07-29 05:30:04 +00:00
|
|
|
|
2004-03-17 14:54:32 +00:00
|
|
|
/* helper function to change the volume by a certain amount, +/-
|
|
|
|
ripped from video.c */
|
2011-10-04 19:33:52 +00:00
|
|
|
static void change_volume(int delta)
|
2008-11-25 13:48:40 +00:00
|
|
|
{
|
2005-12-17 21:13:30 +00:00
|
|
|
int minvol = rb->sound_min(SOUND_VOLUME);
|
|
|
|
int maxvol = rb->sound_max(SOUND_VOLUME);
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
int vol = rb->global_settings->volume + delta;
|
2005-12-17 21:13:30 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if (vol > maxvol) vol = maxvol;
|
|
|
|
else if(vol < minvol) vol = minvol;
|
|
|
|
if(vol != rb->global_settings->volume)
|
|
|
|
{
|
2004-03-12 08:21:26 +00:00
|
|
|
rb->global_settings->volume = vol;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
tweak_volume(part->volume);
|
|
|
|
trigger_display(display_state);
|
2004-03-12 08:21:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-01-14 02:39:30 +00:00
|
|
|
/*function to accelerate bpm change*/
|
2011-10-04 19:33:52 +00:00
|
|
|
static void change_bpm(int direction)
|
2008-11-25 13:48:40 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if( (bpm_step_counter < 20)
|
|
|
|
|| (bpm > 389)
|
|
|
|
|| (bpm < 10) )
|
2006-01-14 02:39:30 +00:00
|
|
|
bpm = bpm + direction;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
else if(bpm_step_counter < 60)
|
2006-01-14 02:39:30 +00:00
|
|
|
bpm = bpm + direction * 2;
|
|
|
|
else
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
bpm = bpm + direction * 9;
|
|
|
|
|
|
|
|
if(bpm > 400) bpm = 400;
|
|
|
|
if(bpm < 1) bpm = 1;
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
part->bpm = bpm;
|
2006-01-14 02:39:30 +00:00
|
|
|
calc_period();
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
trigger_display(display_state);
|
2006-01-14 02:39:30 +00:00
|
|
|
bpm_step_counter++;
|
2007-07-29 05:30:04 +00:00
|
|
|
}
|
2006-01-14 02:39:30 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* I presume the timer ensures that not more than one instance
|
|
|
|
of the callback is running at a given time. */
|
2011-10-04 19:33:52 +00:00
|
|
|
static void timer_callback(void)
|
2006-01-10 02:51:50 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
++minitick;
|
|
|
|
|
|
|
|
/* Clear blinker if tempo is slow enough. */
|
|
|
|
if( (bpm*part->base_beat)/4 <= blinklimit &&
|
|
|
|
!sound_paused && minitick == period/2 )
|
|
|
|
trigger_display(0);
|
|
|
|
|
|
|
|
if(minitick >= period)
|
|
|
|
{
|
2006-01-10 02:51:50 +00:00
|
|
|
minitick = 0;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(!sound_active && !sound_paused && !tap_count)
|
|
|
|
{
|
|
|
|
sound_trigger = true;
|
2006-01-10 02:51:50 +00:00
|
|
|
rb->reset_poweroff_timer();
|
|
|
|
}
|
2004-08-28 09:07:21 +00:00
|
|
|
}
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(tap_count)
|
|
|
|
{
|
2004-11-26 13:31:40 +00:00
|
|
|
tap_time++;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(tap_count > 1 && tap_time > tap_timeout)
|
2004-11-26 13:31:40 +00:00
|
|
|
tap_count = 0;
|
|
|
|
}
|
2004-05-26 06:56:18 +00:00
|
|
|
}
|
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* Stopping playback means incrementing the beat. Normally, it would be
|
|
|
|
incremented after the passing of the current note duration, naturally
|
|
|
|
while starting the next one. */
|
|
|
|
static void metronome_pause(void)
|
2004-10-12 23:45:25 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(beating)
|
|
|
|
{
|
|
|
|
/* Finish the current beat. */
|
|
|
|
advance_beat();
|
|
|
|
beating = false;
|
|
|
|
}
|
|
|
|
sound_paused = true;
|
|
|
|
trigger_display(0);
|
2005-07-26 20:01:11 +00:00
|
|
|
rb->timer_unregister();
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void metronome_unpause(void)
|
|
|
|
{
|
|
|
|
sound_paused = false;
|
|
|
|
minitick = period; /* Start playing immediately (or after a millisecond). */
|
|
|
|
/* Conserve power: Only start timer when actually playing. */
|
|
|
|
rb->timer_register( 1, NULL, TIMER_FREQ/timerfreq_div
|
|
|
|
, timer_callback IF_COP(, CPU) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cleanup(void)
|
|
|
|
{
|
|
|
|
if(fd >= 0) rb->close(fd);
|
|
|
|
|
|
|
|
metronome_pause();
|
2006-01-10 02:51:50 +00:00
|
|
|
MET_PLAY_STOP; /* stop audio ISR */
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
tweak_volume(0);
|
2007-07-29 03:43:37 +00:00
|
|
|
rb->led(0);
|
2010-08-24 14:30:46 +00:00
|
|
|
rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
|
2004-10-12 23:45:25 +00:00
|
|
|
}
|
2004-05-26 06:56:18 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/*
|
|
|
|
Parse part definitions from tempomap file (see header for format).
|
|
|
|
Not bothering with encoding issues here.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* parse meter spec into part structure if given token matches */
|
|
|
|
static bool parse_meter(char *token, struct part *ps)
|
2004-11-26 13:31:40 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
char *toktok;
|
|
|
|
/* Careful not to misinterpret accelerated tempo specification:
|
|
|
|
120-150/4 -> tempo
|
|
|
|
3/4 -> meter */
|
|
|
|
if( !rb->strchr(token, '-') && (toktok = rb->strchr(token, '/')) )
|
|
|
|
{
|
|
|
|
/* Number before and after the '/'. */
|
|
|
|
int num[2];
|
|
|
|
num[0] = rb->atoi(token);
|
|
|
|
num[1] = rb->atoi(++toktok);
|
|
|
|
/* Only accept positive numbers. */
|
|
|
|
if(num[0] > 0 && num[1] > 0)
|
|
|
|
{
|
|
|
|
ps->beats_per_bar = (unsigned int) num[0];
|
|
|
|
ps->base_beat = (unsigned int) num[1];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse tempo, successful when getting a positive integer out of the token. */
|
|
|
|
static bool parse_tempo(char *token, struct part *ps)
|
|
|
|
{
|
|
|
|
char *toktok;
|
|
|
|
/* tempo[-tempo2/accel] ... first number always main tempo */
|
|
|
|
int num = rb->atoi(token);
|
|
|
|
/* Only positive numbers. This avoids the pattern string and general
|
|
|
|
strangeness, unless -150 should mean "from previous tempo to 150". */
|
|
|
|
if(num < 1) return false;
|
|
|
|
|
|
|
|
ps->bpm = (unsigned int) num;
|
|
|
|
ps->bpm2 = ps->bpm;
|
|
|
|
ps->accel = 0;
|
|
|
|
/* This parser is not fool-proof. It parses valid data, but could
|
|
|
|
do funny things if you provide tempo/tempo2-accel, for example.
|
|
|
|
My credo is that the application doesn't crash, but if you give rubbish,
|
|
|
|
you'll get rubbish. */
|
|
|
|
if( (toktok = rb->strchr(token, '-')) )
|
|
|
|
{
|
|
|
|
char *subtok = toktok+1;
|
|
|
|
float faccel = 0.;
|
|
|
|
ps->bpm2 = positive(rb->atoi(subtok));
|
|
|
|
/* Parse or compute accel in bpm/bar. */
|
|
|
|
if( (toktok = rb->strchr(subtok, '/')) )
|
|
|
|
{ /* bars/bpm */
|
|
|
|
float c = rb_atof(++toktok);
|
|
|
|
if( (c > 0.f ? c : -c) > 0.0001f)
|
|
|
|
faccel = 1./c;
|
|
|
|
}
|
|
|
|
else if( (toktok = rb->strchr(subtok, '*')) )
|
|
|
|
{ /* bpm/bar */
|
|
|
|
faccel = rb_atof(++toktok);
|
|
|
|
}
|
|
|
|
else if(ps->bars > 0)
|
|
|
|
{ /* Compute from tempo difference and bar count. */
|
|
|
|
faccel = ((float)ps->bpm2 - (float)ps->bpm)/ps->bars;
|
|
|
|
}
|
|
|
|
/* Correct sign for all cases, starting with positive value. */
|
|
|
|
if(faccel < 0) faccel = -faccel;
|
|
|
|
/* Negative only when end tempo is smaller. */
|
|
|
|
if(ps->bpm2 < ps->bpm) faccel = -faccel;
|
|
|
|
/* Convert (quarterbeats-per-minute per bar) -> 1/min, which could be
|
|
|
|
seen as beats-per-minute/beat */
|
|
|
|
faccel *= 1.f / (4.f/ps->base_beat * ps->beats_per_bar); /* 1/min */
|
|
|
|
ps->accel = fp_frac(faccel);
|
|
|
|
} else
|
|
|
|
/* The other fancy variant: One tempo per beat. */
|
|
|
|
if( (toktok = rb->strchr(token, ',')) )
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
char *subtok = token;
|
|
|
|
/* It is a bug when the parser called this before. Alloc once. */
|
|
|
|
if( ps->beat_bpm || !(ps->beat_bpm =
|
|
|
|
mem_allocate(sizeof(unsigned int)*ps->beats_per_bar*ps->bars)) )
|
|
|
|
return false;
|
|
|
|
for(i=0; i<ps->beats_per_bar*ps->bars; ++i)
|
|
|
|
{
|
|
|
|
int num;
|
|
|
|
if(!subtok) return false;
|
|
|
|
if(subtok != token) ++subtok;
|
|
|
|
|
|
|
|
num = rb->atoi(subtok);
|
|
|
|
if(num < 1) return false;
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
ps->beat_bpm[i] = (unsigned int) num;
|
|
|
|
subtok = rb->strchr(subtok, ',');
|
2004-11-26 13:31:40 +00:00
|
|
|
}
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* The metronome pattern.
|
|
|
|
Ensure that the correct meter is present before calling this! */
|
|
|
|
static bool parse_pattern(char *token, struct part *ps)
|
|
|
|
{
|
|
|
|
size_t pi;
|
|
|
|
size_t pats = rb->strlen(token);
|
|
|
|
|
|
|
|
/* First check if the pattern is valid, error out if not. */
|
|
|
|
if(pats != ps->beats_per_bar)
|
|
|
|
return false;
|
|
|
|
for(pi=0; pi<pats; ++pi)
|
|
|
|
switch(token[pi])
|
|
|
|
{
|
|
|
|
case 'X':
|
|
|
|
case 'x':
|
|
|
|
case '.':
|
|
|
|
break;
|
|
|
|
default: return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(ps->pattern || (ps->pattern = mem_allocate(pats))))
|
|
|
|
return false;
|
|
|
|
/* Now store it. */
|
|
|
|
memcpy(ps->pattern, token, pats);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool parse_volume(char *token, struct part *ps)
|
|
|
|
{
|
|
|
|
float factor = rb_atof(token);
|
|
|
|
ps->volume = fp_rint(fp_decibels(fp_frac(factor > 0.f ? factor : 0.f), 16));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check condition, set error code and bail out if violated. */
|
|
|
|
#define CHECK(a, c) if(!(a)){ errcode = c; goto parse_part_revert; }
|
|
|
|
|
|
|
|
static void parse_part(char *line, unsigned int num)
|
|
|
|
{
|
|
|
|
char *saveptr;
|
|
|
|
char *toktok;
|
|
|
|
char *token[5];
|
|
|
|
struct part *ps;
|
|
|
|
size_t tokens = 0;
|
|
|
|
unsigned int errcode = MERR_NOTHING;
|
|
|
|
|
|
|
|
while (isspace(*line)) line++;
|
|
|
|
/* Skip comments and empty lines quickly. */
|
|
|
|
if(line[0] == '#' || line[0] == 0) return;
|
|
|
|
|
|
|
|
mem_checkpoint();
|
|
|
|
CHECK(ps = mem_allocate(sizeof(struct part)), MERR_OOM);
|
|
|
|
part_init(ps);
|
|
|
|
|
|
|
|
/* Check for and store label. */
|
|
|
|
if( (toktok = rb->strchr(line, ':')) )
|
|
|
|
{
|
|
|
|
size_t len = toktok-line;
|
|
|
|
CHECK(ps->label = mem_allocate(len+1), MERR_OOM);
|
|
|
|
rb->memcpy(ps->label, line, len);
|
|
|
|
ps->label[len] = 0;
|
|
|
|
line = toktok+1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CHECK(token[0] = rb->strtok_r(line, " \t", &saveptr), MERR_MISSING);
|
|
|
|
tokens = 1;
|
|
|
|
/* After the optional label, there can be up to 5 tokens of interest.
|
|
|
|
Collect them in advance to make the parser code more sane. */
|
|
|
|
while( tokens < 5
|
|
|
|
&& (token[tokens] = rb->strtok_r(NULL, " \t", &saveptr)) )
|
|
|
|
{
|
|
|
|
if(token[tokens][0] == '#')
|
|
|
|
break;
|
|
|
|
++tokens;
|
|
|
|
}
|
|
|
|
|
|
|
|
CHECK(tokens >= 2, MERR_MISSING);
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* Now try to be smart about guessing which token can be what value.
|
|
|
|
Remember: Always parse meter before pattern or tempo! */
|
|
|
|
ps->bars = (unsigned int) rb->atoi(token[0]);
|
|
|
|
if(tokens == 2) /* <bars> <tempo> */
|
|
|
|
{
|
|
|
|
CHECK(parse_tempo(token[1], ps), MERR_TEMPO);
|
|
|
|
} else
|
|
|
|
if(tokens == 3)
|
|
|
|
{
|
|
|
|
/* <bars> <meter> <tempo> */
|
|
|
|
if(parse_meter(token[1], ps))
|
|
|
|
{
|
|
|
|
CHECK(parse_tempo(token[2], ps), MERR_TEMPO);
|
|
|
|
} else
|
|
|
|
/* <bars> <tempo> <pattern> */
|
|
|
|
if(parse_pattern(token[2], ps))
|
|
|
|
{
|
|
|
|
CHECK(parse_tempo(token[1], ps), MERR_TEMPO);
|
|
|
|
} else
|
|
|
|
/* <bars> <tempo> <volume> */
|
|
|
|
{
|
|
|
|
CHECK(parse_tempo(token[1], ps), MERR_TEMPO);
|
|
|
|
CHECK(parse_volume(token[2], ps), MERR_VOLUME);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
if(tokens == 4)
|
|
|
|
{
|
|
|
|
/* <bars> <meter> <tempo> <pattern> */
|
|
|
|
if(parse_meter(token[1], ps) && parse_pattern(token[3], ps))
|
|
|
|
{
|
|
|
|
CHECK(parse_tempo(token[2], ps), MERR_TEMPO);
|
|
|
|
} else
|
|
|
|
/* <bars> <tempo> <pattern> <volume> */
|
|
|
|
if(parse_pattern(token[2], ps))
|
|
|
|
{
|
|
|
|
CHECK(parse_tempo(token[1], ps), MERR_TEMPO);
|
|
|
|
CHECK(parse_volume(token[3], ps), MERR_VOLUME);
|
|
|
|
} else
|
|
|
|
/* <bars> <meter> <tempo> <volume> */
|
|
|
|
{
|
|
|
|
CHECK(parse_meter(token[1], ps), MERR_METER);
|
|
|
|
CHECK(parse_tempo(token[2], ps), MERR_TEMPO);
|
|
|
|
CHECK(parse_volume(token[3], ps), MERR_VOLUME);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
if(tokens == 5) /* the complete set */
|
|
|
|
{
|
|
|
|
/* <bars> <meter> <tempo> <pattern> <volume> */
|
|
|
|
CHECK(parse_meter(token[1], ps), MERR_METER);
|
|
|
|
CHECK(parse_tempo(token[2], ps), MERR_TEMPO);
|
|
|
|
CHECK(parse_pattern(token[3], ps), MERR_PATTERN);
|
|
|
|
CHECK(parse_volume(token[4], ps), MERR_VOLUME);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!ps->pattern)
|
|
|
|
{
|
|
|
|
/* For parsed parts default to emphasize every first beat. */
|
|
|
|
CHECK(ps->pattern = mem_allocate(ps->beats_per_bar), MERR_OOM);
|
|
|
|
memset(ps->pattern, 'x', ps->beats_per_bar);
|
|
|
|
ps->pattern[0] = 'X';
|
|
|
|
}
|
|
|
|
|
|
|
|
part_add(ps);
|
|
|
|
return; /* all good */
|
|
|
|
|
|
|
|
/* Remove part after some error. */
|
|
|
|
parse_part_revert:
|
|
|
|
rb->snprintf(buffer, sizeof(buffer), "ERR %u @line %u", errcode, num);
|
|
|
|
rb->splash(2*HZ, buffer);
|
|
|
|
++bad_parts;
|
|
|
|
mem_reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef CHECK
|
|
|
|
|
|
|
|
static void step_back(void)
|
|
|
|
{
|
|
|
|
beating = false;
|
|
|
|
beat = 0;
|
|
|
|
if(bar)
|
|
|
|
{
|
|
|
|
/* Endless parts only know position 0 to step to. */
|
|
|
|
if(part->bars) --bar;
|
|
|
|
else bar = 0;
|
|
|
|
}
|
|
|
|
else if(part->prev)
|
|
|
|
{
|
|
|
|
part = part->prev;
|
|
|
|
/* This will jump to bar 0 for endless parts. */
|
|
|
|
bar = positive(part->bars)-1;
|
|
|
|
tweak_volume(part->volume);
|
|
|
|
}
|
|
|
|
/* Always calculate period for acceleration. */
|
|
|
|
calc_period();
|
|
|
|
minitick = period;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void step_forw(void)
|
|
|
|
{
|
|
|
|
beating = false;
|
|
|
|
/* Stepping forward in endless part always goes to the next one, if any. */
|
|
|
|
if(part->bars == 0 || bar+1 == part->bars)
|
|
|
|
{
|
|
|
|
if(part->next)
|
|
|
|
{ /* Advanced one part. */
|
|
|
|
part = part->next;
|
|
|
|
bar = 0;
|
|
|
|
beat = 0;
|
|
|
|
tweak_volume(part->volume);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else ++bar;
|
|
|
|
/* Always calculate period for acceleration. */
|
|
|
|
calc_period();
|
|
|
|
minitick = period;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tap(void)
|
|
|
|
{
|
|
|
|
struct part *ps = part;
|
|
|
|
|
|
|
|
/* Each tap resets the position. */
|
|
|
|
beat = 0;
|
|
|
|
bar = 0;
|
|
|
|
|
|
|
|
if(tap_count == 0 || tap_time < tap_count)
|
|
|
|
tap_time = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(tap_time > 0)
|
|
|
|
{
|
|
|
|
/* Could use fixed point math and rounding, even. */
|
|
|
|
ps->bpm = 60*timerfreq_div*tap_count/tap_time;
|
|
|
|
|
|
|
|
if(ps->bpm > 400) ps->bpm = 400;
|
|
|
|
}
|
2004-11-26 13:31:40 +00:00
|
|
|
tap_timeout = (tap_count+2)*tap_time/tap_count;
|
|
|
|
}
|
2007-07-29 05:30:04 +00:00
|
|
|
|
2004-11-26 13:31:40 +00:00
|
|
|
tap_count++;
|
|
|
|
minitick = 0; /* sync tock to tapping */
|
|
|
|
reset_tap = false;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
play_ticktock();
|
2004-11-26 13:31:40 +00:00
|
|
|
}
|
2004-03-12 08:21:26 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
enum plugin_status plugin_start(const void* file)
|
2008-11-25 13:48:40 +00:00
|
|
|
{
|
2004-10-12 23:45:25 +00:00
|
|
|
int button;
|
2010-05-20 17:41:28 +00:00
|
|
|
static int last_button = BUTTON_NONE;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
bool common_action;
|
2004-10-12 23:45:25 +00:00
|
|
|
|
2010-08-24 14:30:46 +00:00
|
|
|
atexit(cleanup);
|
2004-03-12 08:21:26 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
mem_init();
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(MET_IS_PLAYING) MET_PLAY_STOP; /* stop audio IS */
|
|
|
|
|
|
|
|
prepare_buffers();
|
2007-06-10 02:10:47 +00:00
|
|
|
#if INPUT_SRC_CAPS != 0
|
|
|
|
/* Select playback */
|
|
|
|
rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
|
|
|
|
rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
|
|
|
|
#endif
|
|
|
|
rb->pcm_set_frequency(SAMPR_44);
|
2004-03-12 08:21:26 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(file)
|
|
|
|
{
|
|
|
|
parts = 0;
|
|
|
|
bad_parts = 0;
|
|
|
|
fd = rb->open(file, O_RDONLY);
|
|
|
|
if(fd >= 0)
|
|
|
|
{
|
|
|
|
unsigned int linenum = 0;
|
|
|
|
/* Crazyness, allocating line buffer depending on free memory. */
|
|
|
|
linebuf_size = mem_end - mem_free_region > 32*1024
|
|
|
|
? 1024
|
|
|
|
: ( mem_end - mem_free_region > 16*1024
|
|
|
|
? 256
|
|
|
|
: 128 );
|
|
|
|
if(!(linebuf = mem_allocate(linebuf_size))) return PLUGIN_ERROR;
|
|
|
|
/* I'm assuming that read_line always terminates. */
|
|
|
|
while(rb->read_line(fd, linebuf, linebuf_size) > 0)
|
|
|
|
{
|
|
|
|
parse_part(linebuf, ++linenum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rb->close(fd);
|
|
|
|
if(bad_parts)
|
|
|
|
{
|
|
|
|
rb->snprintf(buffer, sizeof(buffer), "%u bad parts", bad_parts);
|
|
|
|
rb->splash(2*HZ, buffer);
|
|
|
|
}
|
|
|
|
if(!parts)
|
|
|
|
{
|
|
|
|
rb->splash(2*HZ, "Got no parts. Bye!");
|
|
|
|
return PLUGIN_OK;
|
|
|
|
}
|
|
|
|
}
|
2007-07-29 05:30:04 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* If no parts given, start in simple metronome mode. */
|
|
|
|
if(!parts)
|
|
|
|
{ /* Just checking the early bailout here. */
|
|
|
|
struct part *ps = mem_allocate(sizeof(struct part));
|
|
|
|
if(!ps) return PLUGIN_ERROR;
|
|
|
|
part_init(ps);
|
|
|
|
part_add(ps);
|
|
|
|
track_mode = false;
|
|
|
|
}
|
|
|
|
else track_mode = true;
|
|
|
|
|
|
|
|
part = part_list;
|
|
|
|
tweak_volume(part->volume);
|
|
|
|
calc_period();
|
2004-11-26 13:31:40 +00:00
|
|
|
draw_display();
|
2004-03-12 08:21:26 +00:00
|
|
|
|
|
|
|
/* main loop */
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
while(true)
|
|
|
|
{
|
2004-11-26 13:31:40 +00:00
|
|
|
reset_tap = true;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
button = pluginlib_getaction( TIMEOUT_NOBLOCK, plugin_contexts
|
|
|
|
, PLA_ARRAY_COUNT );
|
|
|
|
if(sound_trigger)
|
2007-04-12 17:58:42 +00:00
|
|
|
{
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
sound_trigger = false;
|
|
|
|
play_ticktock(); /* Draws display before playback. */
|
|
|
|
}
|
|
|
|
|
|
|
|
common_action = false;
|
|
|
|
if(track_mode)
|
|
|
|
{
|
|
|
|
switch(button)
|
|
|
|
{
|
|
|
|
case METRONOME_START:
|
|
|
|
if(sound_paused) metronome_unpause();
|
|
|
|
else metronome_pause();
|
|
|
|
break;
|
|
|
|
case METRONOME_PAUSE:
|
|
|
|
if(!sound_paused) metronome_pause();
|
|
|
|
break;
|
|
|
|
case METRONOME_LEFT:
|
|
|
|
case METRONOME_LEFT_REP:
|
|
|
|
step_back();
|
|
|
|
trigger_display(0);
|
|
|
|
break;
|
|
|
|
case METRONOME_RIGHT:
|
|
|
|
case METRONOME_RIGHT_REP:
|
|
|
|
step_forw();
|
|
|
|
trigger_display(0);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
common_action = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch(button)
|
|
|
|
{
|
|
|
|
case METRONOME_PAUSE:
|
|
|
|
if(!sound_paused) metronome_pause();
|
|
|
|
break;
|
|
|
|
case METRONOME_PLAY:
|
|
|
|
if(sound_paused) metronome_unpause();
|
|
|
|
break;
|
|
|
|
case METRONOME_TAP:
|
|
|
|
if(last_button != METRONOME_PLAY)
|
|
|
|
{
|
|
|
|
if(sound_paused) metronome_unpause();
|
|
|
|
tap();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case METRONOME_LEFT:
|
|
|
|
bpm_step_counter = 0;
|
2021-07-24 14:39:01 +00:00
|
|
|
/* fallthrough */
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
case METRONOME_LEFT_REP:
|
|
|
|
change_bpm(-1);
|
|
|
|
break;
|
|
|
|
case METRONOME_RIGHT:
|
|
|
|
bpm_step_counter = 0;
|
2021-07-24 14:39:01 +00:00
|
|
|
/* fallthrough */
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
case METRONOME_RIGHT_REP:
|
|
|
|
change_bpm(1);
|
|
|
|
break;
|
|
|
|
#ifdef MET_SYNC
|
|
|
|
case METRONOME_SYNC:
|
|
|
|
minitick = period;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
common_action = true;
|
|
|
|
}
|
2007-04-12 17:58:42 +00:00
|
|
|
}
|
2004-11-26 13:31:40 +00:00
|
|
|
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(common_action)
|
|
|
|
switch(button)
|
|
|
|
{
|
2004-11-26 13:31:40 +00:00
|
|
|
case METRONOME_QUIT:
|
|
|
|
/* get out of here */
|
2010-08-24 14:30:46 +00:00
|
|
|
return PLUGIN_OK;
|
2004-11-26 13:31:40 +00:00
|
|
|
case METRONOME_VOL_UP:
|
2006-11-16 02:53:44 +00:00
|
|
|
case METRONOME_VOL_UP_REP:
|
2004-11-26 13:31:40 +00:00
|
|
|
change_volume(1);
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
trigger_display(0);
|
2004-11-26 13:31:40 +00:00
|
|
|
break;
|
|
|
|
case METRONOME_VOL_DOWN:
|
2006-11-16 02:53:44 +00:00
|
|
|
case METRONOME_VOL_DOWN_REP:
|
2004-11-26 13:31:40 +00:00
|
|
|
change_volume(-1);
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
trigger_display(0);
|
2004-11-26 13:31:40 +00:00
|
|
|
break;
|
|
|
|
default:
|
2010-08-24 14:30:46 +00:00
|
|
|
exit_on_usb(button);
|
2004-11-26 13:31:40 +00:00
|
|
|
reset_tap = false;
|
|
|
|
break;
|
|
|
|
}
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
|
|
|
|
if(button)
|
2010-05-20 17:41:28 +00:00
|
|
|
last_button = button;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
if(reset_tap)
|
2004-11-26 13:31:40 +00:00
|
|
|
tap_count = 0;
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
/* If there was some action, display drawing is still needed.
|
|
|
|
This _might_ disturb audio on slow machines, but
|
|
|
|
then, you could just stop pressing buttons, then;-) */
|
|
|
|
if(display_trigger)
|
|
|
|
{
|
|
|
|
display_trigger = false;
|
|
|
|
draw_display();
|
2004-11-26 13:31:40 +00:00
|
|
|
}
|
Enhancement of the metronome plugin:
- square sine tick and tock sounds (more annoying, more useful;-)
- optical indication of tics on display
- unification of mode of operation for SWCODEC and HWCODEC (tested on simulator)
Both playback and display drawing happen in main loop, always.
- operating in two modes now:
-- 1. classic dumb metronome
--- active when openened as application without file to open
--- the usual functionality with tapping and bpm change
--- controls indicated on display
-- 2. track mode with programmable series of parts
--- active when started as viewer for a .tempo file
--- differing meters (4/4, 3/4, 6/8, etc.)
--- patterns (tick/tock/silence on each beat)
--- smooth tempo changes in those tracks
This version had lots of testing regarding metronome accuracy,
resulting in the realization that PLL A and PLL B differ
on the Clip+, causing drift. There is still drift when the timer
intervall is too small, so I settled on 2 ms as compromise.
This is the final version, after adding documentation and extensive
help from Sebastian Leonhardt testing it on slower hardware (YH820),
where it works up to 650 actual bpm with display indication.
Latest change: Documentation nitpicks.
Change-Id: I764c8252526db188352385c5462f9453d882beb9
2014-06-29 13:59:11 +00:00
|
|
|
|
|
|
|
/* This determines the accuracy of the metronome with SWCODEC ... the
|
|
|
|
scheduler decides when we are allowed to play. */
|
2010-07-01 13:35:16 +00:00
|
|
|
rb->yield();
|
2004-03-12 08:21:26 +00:00
|
|
|
}
|
|
|
|
}
|