Stuarts tone and menu UI frameowrk - thanks Stuart!
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 23 Sep 2015 00:54:13 +0000 (00:54 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 23 Sep 2015 00:54:13 +0000 (00:54 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2349 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/stm32/src/sfx.c [new file with mode: 0644]
codec2-dev/stm32/src/sfx.h [new file with mode: 0644]
codec2-dev/stm32/src/sounds.c [new file with mode: 0644]
codec2-dev/stm32/src/sounds.h [new file with mode: 0644]
codec2-dev/stm32/src/tone.c [new file with mode: 0644]
codec2-dev/stm32/src/tone.h [new file with mode: 0644]

diff --git a/codec2-dev/stm32/src/sfx.c b/codec2-dev/stm32/src/sfx.c
new file mode 100644 (file)
index 0000000..293522e
--- /dev/null
@@ -0,0 +1,67 @@
+/*!
+ * Sound effect player library.
+ *
+ * This implements a state machine for playing back various monophonic
+ * sound effects such as morse code symbols, clicks and alert tones.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include "sfx.h"
+
+static void sfx_next_tone(struct sfx_player_t* const sfx_player)
+{
+       struct tone_gen_t* tone_gen = &(sfx_player->tone_gen);
+       const struct sfx_note_t* note = sfx_player->note;
+
+       if (!note) {
+               tone_reset(tone_gen, 0, 0);
+       } else {
+               tone_reset(tone_gen, note->freq, note->duration);
+
+               if (!note->duration)
+                       /* We are done */
+                       sfx_player->note = NULL;
+               else
+                       /* Move to next note */
+                       sfx_player->note++;
+       }
+}
+
+/*!
+ * Start playing a particular effect.
+ * @param      sfx_player      Effect player state machine
+ * @param      effect          Pointer to sound effect (NULL == stop)
+ */
+void sfx_play(struct sfx_player_t* const sfx_player,
+               const struct sfx_note_t* effect)
+{
+       sfx_player->note = effect;
+       sfx_next_tone(sfx_player);
+}
+
+/*!
+ * Retrieve the next sample to be played.
+ */
+int16_t sfx_next(struct sfx_player_t* const sfx_player)
+{
+       if (!sfx_player)
+               return(0);
+       if (!sfx_player->tone_gen.remain)
+               sfx_next_tone(sfx_player);
+       return tone_next(&(sfx_player->tone_gen));
+}
diff --git a/codec2-dev/stm32/src/sfx.h b/codec2-dev/stm32/src/sfx.h
new file mode 100644 (file)
index 0000000..3ac8d5a
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef _SFX_H
+#define _SFX_H
+/*!
+ * Sound effect player library.
+ *
+ * This implements a state machine for playing back various monophonic
+ * sound effects such as morse code symbols, clicks and alert tones.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "tone.h"
+
+/*!
+ * A sound effect "note"
+ */
+struct sfx_note_t {
+       /*! Note frequency.  0 == pause */
+       uint16_t        freq;
+       /*! Note duration in msec.   0 == end of effect */
+       uint16_t        duration;
+};
+
+/*!
+ * Sound effect player state machine
+ */
+struct sfx_player_t {
+       /*!
+        * Pointer to the current "note".  When this is NULL,
+        * playback is complete.
+        */
+       const struct sfx_note_t*        note;
+       /*! Tone generator state machine */
+       struct tone_gen_t               tone_gen;
+};
+
+/*!
+ * Start playing a particular effect.
+ * @param      sfx_player      Effect player state machine
+ * @param      effect          Pointer to sound effect (NULL == stop)
+ */
+void sfx_play(struct sfx_player_t* const sfx_player,
+               const struct sfx_note_t* effect);
+
+/*!
+ * Retrieve the next sample to be played.
+ */
+int16_t sfx_next(struct sfx_player_t* const sfx_player);
+
+#endif
diff --git a/codec2-dev/stm32/src/sounds.c b/codec2-dev/stm32/src/sounds.c
new file mode 100644 (file)
index 0000000..b79b641
--- /dev/null
@@ -0,0 +1,36 @@
+/*!
+ * Sound effect library.
+ *
+ * This provides some sound effects for the SM1000 UI.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sounds.h"
+
+/*! Start-up tune */
+struct sfx_note_t sound_startup[] = {
+       {.freq = 600, .duration = 80},
+       {.freq = 800, .duration = 80},
+       {.freq = 1000, .duration = 80},
+       {.freq = 0, .duration = 0}
+};
+
+/*! Click sound */
+struct sfx_note_t sound_click[] = {
+       {.freq = 1200, .duration = 10},
+       {.freq = 0, .duration = 0}
+};
diff --git a/codec2-dev/stm32/src/sounds.h b/codec2-dev/stm32/src/sounds.h
new file mode 100644 (file)
index 0000000..a2e8a01
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _SOUNDS_H
+#define _SOUNDS_H
+/*!
+ * Sound effect library.
+ *
+ * This provides some sound effects for the SM1000 UI.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sfx.h"
+
+/*! Start-up tune */
+extern struct sfx_note_t sound_startup[];
+
+/*! Click sound */
+extern struct sfx_note_t sound_click[];
+
+#endif
diff --git a/codec2-dev/stm32/src/tone.c b/codec2-dev/stm32/src/tone.c
new file mode 100644 (file)
index 0000000..7f02fa5
--- /dev/null
@@ -0,0 +1,114 @@
+/*!
+ * Fixed-point tone generator.
+ *
+ * The code here implements a simple fixed-point tone generator that uses
+ * integer arithmetic to generate a sinusoid at a fixed sample rate of
+ * 16kHz.
+ *
+ * To set the initial state of the state machine, you specify a frequency
+ * and duration using tone_reset.  The corresponding C file embeds a
+ * sinusoid look-up table.  The total number of samples is computed for
+ * the given time and used to initialise 'remain', 'time' is initialised
+ * to 0, and 'step' gives the amount to increment 'time' by each iteration.
+ *
+ * The samples are retrieved by repeatedly calling tone_next.  This
+ * advances 'time' and decrements 'remain'.  The tone is complete when
+ * 'remain' is zero.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV <me@vk4msl.id.au>tors.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "tone.h"
+
+/*! Fixed-point shift factor */
+#define TONE_SHIFT     (12)
+
+/*! Static compiled sinusoid.  Nicked from original FreeDV code. */
+static const int16_t tone_sine[] = {
+     -16,    6384,   12528,   18192,   23200,   27232,   30256,   32128,
+   32752,   32128,   30256,   27232,   23152,   18192,   12528,    6384,
+     -16,   -6416,  -12560,  -18224,  -23184,  -27264,  -30288,  -32160,
+  -32768,  -32160,  -30288,  -27264,  -23184,  -18224,  -12560,   -6416
+};
+
+/*! Length of sinusoid in samples */
+#define TONE_SINE_LEN  (sizeof(tone_sine)/sizeof(tone_sine[0]))
+
+/*!
+ * Re-set the tone generator.
+ *
+ * @param      tone_gen        Tone generator to reset.
+ * @param      freq            Frequency in Hz, 0 = silence.
+ * @param      duration        Duration in milliseconds.  0 to stop.
+ */
+void tone_reset(
+       struct tone_gen_t* const tone_gen,
+       uint16_t freq, uint16_t duration)
+{
+       if (freq)
+               /* Compute the time step */
+               tone_gen->step = (((2*freq*TONE_SINE_LEN) << TONE_SHIFT)
+                               / ((2*TONE_FS) + 1) + 1);
+       else
+               /* DC tone == silence */
+               tone_gen->step = 0;
+
+       /* Compute remaining samples */
+       tone_gen->remain = (uint16_t)(
+                       ((uint32_t)(TONE_FS * duration)) / 1000);
+
+       /* Initialise the sample counter */
+       tone_gen->sample = 0;
+}
+
+/*!
+ * Retrieve the next sample from the tone generator.
+ * @param      tone_gen        Tone generator to update.
+ */
+int16_t tone_next(
+       struct tone_gen_t* const tone_gen)
+{
+       if (!tone_gen)
+               return 0;
+       if (!tone_gen->remain)
+               return 0;
+       if (!tone_gen->step) {
+               /* Special case, emit silence */
+               tone_gen->remain--;
+               return 0;
+       }
+
+       /* Compute sample index */
+       uint16_t sample_int = ((tone_gen->sample) >> TONE_SHIFT)
+                               % TONE_SINE_LEN;
+
+       /* Advance tone generator state */
+       tone_gen->sample += tone_gen->step;
+       tone_gen->remain--;
+
+       return tone_sine[sample_int];
+}
+
+/*!
+ * Retrieve the current time in milliseconds.
+ */
+uint32_t tone_msec(const struct tone_gen_t* const tone_gen)
+{
+       uint64_t ms = tone_gen->sample;
+       ms *= 1000;
+       ms /= TONE_FS;
+       return ms >> TONE_SHIFT;
+}
diff --git a/codec2-dev/stm32/src/tone.h b/codec2-dev/stm32/src/tone.h
new file mode 100644 (file)
index 0000000..a8ed89a
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _TONE_H
+#define _TONE_H
+/*!
+ * Fixed-point tone generator.
+ *
+ * The code here implements a simple fixed-point tone generator that uses
+ * integer arithmetic to generate a sinusoid at a fixed sample rate of
+ * 16kHz.
+ *
+ * To set the initial state of the state machine, you specify a frequency
+ * and duration using tone_reset.  The corresponding C file embeds a
+ * sinusoid look-up table.  The total number of samples is computed for
+ * the given time and used to initialise 'remain', 'time' is initialised
+ * to 0, and 'step' gives the amount to increment 'time' by each iteration.
+ *
+ * The samples are retrieved by repeatedly calling tone_next.  This
+ * advances 'time' and decrements 'remain'.  The tone is complete when
+ * 'remain' is zero.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+/*! Tone sampling rate in Hz. */
+#define TONE_FS        16000
+
+/*!
+ * Tone generator state.  This holds the current state of the tone
+ * generator in order to decide what sample to release next.
+ */
+struct tone_gen_t {
+       /*! Current sample.  (Q12) */
+       uint32_t        sample;
+       /*!
+        * Time remaining in samples. (integer)  Playback is finished
+        * when this reaches zero.
+        */
+       uint16_t        remain;
+       /*!
+        * Subsample step (Q12).  This is the number of samples (or part
+        * thereof) to advance "sample".  Special case: when zero, sample
+        * is not advanced, silence is generated instead.
+        */
+       uint16_t        step;
+};
+
+/*!
+ * Re-set the tone generator.
+ *
+ * @param      tone_gen        Tone generator to reset.
+ * @param      freq            Frequency in Hz, 0 = silence.
+ * @param      duration        Duration in milliseconds.  0 to stop.
+ */
+void tone_reset(
+       struct tone_gen_t* const tone_gen,
+       uint16_t freq, uint16_t duration);
+
+/*!
+ * Retrieve the next sample from the tone generator.
+ * @param      tone_gen        Tone generator to update.
+ */
+int16_t tone_next(
+       struct tone_gen_t* const tone_gen);
+
+/*!
+ * Retrieve the current time in milliseconds.
+ */
+uint32_t tone_msec(const struct tone_gen_t* const tone_gen);
+
+#endif