You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.6 KiB
89 lines
2.6 KiB
/** @file tweeter.h
|
|
@author M. P. Hayes, UCECE
|
|
@date 20 April 2007
|
|
@brief Generate PWM for a piezo tweeter.
|
|
*/
|
|
#ifndef TWEETER_H
|
|
#define TWEETER_H
|
|
|
|
#include "system.h"
|
|
#include "ticker.h"
|
|
|
|
typedef uint8_t tweeter_note_t;
|
|
typedef uint8_t tweeter_duration_t;
|
|
typedef uint8_t tweeter_period_t;
|
|
typedef uint8_t tweeter_velocity_t;
|
|
typedef uint8_t tweeter_scale_t;
|
|
|
|
/* We could calculate scale divisors at run time. 2^(1/2) is approx
|
|
1.0594631. A reasonable rational approximation is 267/252 =
|
|
1.0595238.
|
|
|
|
Let's save memory and provide a macro to compute the
|
|
divisors. There is only 8 bits per note so the maximum POLL_RATE
|
|
is 255 * 82.41 = 21014 Hz. If we use a lower rate then the divisors
|
|
become less accurate, especially at the higher frequencies. For example,
|
|
with C5, f = 523 Hz, and if POLL_RATE = 10000, then the divisor is 19
|
|
giving a generated frequency of 526 Hz.
|
|
*/
|
|
|
|
#define TWEETER_DIVISOR(POLL_RATE, FREQ) (POLL_RATE / FREQ + 0.5)
|
|
|
|
|
|
enum {TWEETER_NOTE_MIN = 40};
|
|
/* Define divisors for chromatic scale E2 -> D#3. For better accuracy
|
|
this should be defined for the lowest frequency scale, however,
|
|
this may need 16 bits per note. */
|
|
#define TWEETER_SCALE_TABLE(POLL_RATE) \
|
|
{TWEETER_DIVISOR (POLL_RATE, 82.41), \
|
|
TWEETER_DIVISOR (POLL_RATE, 87.31), \
|
|
TWEETER_DIVISOR (POLL_RATE, 92.50), \
|
|
TWEETER_DIVISOR (POLL_RATE, 98.00), \
|
|
TWEETER_DIVISOR (POLL_RATE, 103.83), \
|
|
TWEETER_DIVISOR (POLL_RATE, 110.0), \
|
|
TWEETER_DIVISOR (POLL_RATE, 116.54), \
|
|
TWEETER_DIVISOR (POLL_RATE, 123.47), \
|
|
TWEETER_DIVISOR (POLL_RATE, 130.81), \
|
|
TWEETER_DIVISOR (POLL_RATE, 138.59), \
|
|
TWEETER_DIVISOR (POLL_RATE, 146.83), \
|
|
TWEETER_DIVISOR (POLL_RATE, 155.56)}
|
|
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t note_clock;
|
|
uint8_t note_period;
|
|
uint8_t note_duty;
|
|
uint16_t poll_rate;
|
|
tweeter_scale_t *scale_table;
|
|
} tweeter_private_t;
|
|
|
|
|
|
typedef tweeter_private_t tweeter_obj_t;
|
|
typedef tweeter_obj_t *tweeter_t;
|
|
|
|
/* The scale table is usually defined with:
|
|
static tweeter_scale_t scale_table[] = TWEETER_SCALE_TABLE (LOOP_POLL_RATE);
|
|
*/
|
|
|
|
|
|
/** Decide whether to turn tweeter on. */
|
|
bool
|
|
tweeter_update (tweeter_t tweeter);
|
|
|
|
|
|
/* The note and velocity are specified as per the MIDI standard except
|
|
a note value of 0 indicates a rest (note off). The velocity has a
|
|
maximum value of 127 and gives an indication of the note
|
|
volume. */
|
|
void
|
|
tweeter_note_play (tweeter_t tweeter, tweeter_note_t note, uint8_t velocity);
|
|
|
|
|
|
tweeter_t
|
|
tweeter_init (tweeter_obj_t *dev,
|
|
uint16_t poll_rate,
|
|
tweeter_scale_t *scale_table);
|
|
|
|
#endif
|