Sound sample and sinewave playback driver definitions.
Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
#include <board.h>
#include <compiler.h>
#include <dac.h>
#include <string.h>
#include <nvm.h>
#include <tc.h>
#include "sound.h"
#include "snd_samples.h"
#include "get_far.h"
Macros | |
#define | SOUND_DDS_RES (0xFFFFFFFFUL / SOUND_SAMPLE_RATE) |
Direct Digital Synthesization residue. More... | |
#define | SOUND_SINEWAVE_VOICES 8 |
Number of concurrent sinewaves that can be output. More... | |
Functions | |
void | sample_callback (void) |
Callback function for updating DAC sample value. More... | |
static uint16_t | sound_get_16_bit_sample (uint32_t snd_ptr, uint16_t smpl_cnt) |
Get 16-bit sample from soundtable. More... | |
static uint8_t | sound_get_8_bit_sample (uint32_t snd_ptr, uint16_t smpl_cnt) |
Get 8-bit sample from soundtable. More... | |
static uint16_t | sound_get_frequency_from_note (uint8_t note) |
Get the frequency of specified note. More... | |
static uint16_t | sound_get_next_sinewave_sample (uint32_t *dds_acc, uint16_t freq) |
Get next sinewave sample by means of DDS (Direct Digital Synth). More... | |
void | sound_init (void) |
Initialize the DAC, timer/counter and event system. More... | |
bool | sound_is_playing (void) |
Convenience function to check if a sound is currently playing. More... | |
void | sound_play_note (uint8_t buttons) |
Set sinewave frequencies to generate. More... | |
void | sound_play_sample (uint8_t buttons) |
Starts playing samples when button status is sent. More... | |
Variables | |
uint16_t | notes [20] |
Table of frequencies for 20 notes, starting at an A (at 441Hz). More... | |
static volatile flash_addr_t | prog_snd_ptr = 0 |
Progmem far flash "pointer". More... | |
static volatile uint16_t | sinefreqs [SOUND_SINEWAVE_VOICES] = {0} |
Table to contain sinewave frequencies – this is polytonal. More... | |
static volatile uint16_t | snd_cnt = 0 |
Current frame in sound. More... | |
static volatile uint16_t | snd_len = 0 |
Number of frames in a sound. More... | |
static uint8_t | snd_samplewidth = 0 |
1 or 2 bytes sample width More... | |
#define SOUND_DDS_RES (0xFFFFFFFFUL / SOUND_SAMPLE_RATE) |
Direct Digital Synthesization residue.
This value represents the value that must be added to the DDS accumulators for every DAC conversion if we wanted to convert one period of the signal every second. Usually, one wants to play at a higher rate than 1 Hertz, so this value is multiplied by the desired frequency, before adding to the accumulator.
Referenced by sound_get_next_sinewave_sample().
#define SOUND_SINEWAVE_VOICES 8 |
Number of concurrent sinewaves that can be output.
Referenced by sample_callback().
void sample_callback | ( | void | ) |
Callback function for updating DAC sample value.
This handles loading of the next sample into the DAC channel data register. Depending on the global variables associated with the currently playing sounds, this will load either a sound sample or the next value for the sinewaves.
The actual DAC conversion is initiated by the overflow event, not this ISR.
The volume is controlled by bit-shifting the sample values. However, if the values are shifted too much, the signal will be severely distorted since the MSBs are lost first.
References acc, dac_set_channel_value(), prog_snd_ptr, sinefreqs, snd_cnt, snd_len, snd_samplewidth, sound_get_16_bit_sample(), sound_get_8_bit_sample(), sound_get_next_sinewave_sample(), SOUND_SINEWAVE_VOICES, and sound_stop_timer().
Referenced by sound_init().
|
inlinestatic |
Get 16-bit sample from soundtable.
snd_ptr | Pointer to start of soundtable. |
smpl_cnt | Sample in table to get. |
References nvm_flash_read_word().
Referenced by sample_callback().
|
inlinestatic |
Get 8-bit sample from soundtable.
snd_ptr | Pointer to start of soundtable. |
smpl_cnt | Sample in table to get. |
References nvm_flash_read_byte().
Referenced by sample_callback().
|
inlinestatic |
Get the frequency of specified note.
note | Note number, must be in range of notes. |
Referenced by sound_play_note().
|
inlinestatic |
Get next sinewave sample by means of DDS (Direct Digital Synth).
dds_acc | Accumulator to be used for calculation and lookup. |
freq | The frequency in Hz that is desired. |
References nvm_flash_read_word(), and SOUND_DDS_RES.
Referenced by sample_callback().
void sound_init | ( | void | ) |
Initialize the DAC, timer/counter and event system.
References DAC_ADJ_LEFT, dac_enable(), DAC_REF_AVCC, dac_set_active_channel(), dac_set_conversion_interval(), dac_set_conversion_parameters(), dac_set_conversion_trigger(), dac_write_configuration(), PMIC_LVL_LOW, sample_callback(), SOUND_SAMPLE_RATE, sysclk_enable_module(), SYSCLK_EVSYS, sysclk_get_per_hz(), SYSCLK_PORT_GEN, tc_enable(), tc_set_overflow_interrupt_callback(), tc_set_overflow_interrupt_level(), and tc_write_period().
Referenced by main().
bool sound_is_playing | ( | void | ) |
Convenience function to check if a sound is currently playing.
true | Sound is currently being played back. |
false | Sound is not being played back. |
References snd_cnt, and snd_len.
Referenced by play_game(), and sound_play_sample().
void sound_play_note | ( | uint8_t | buttons | ) |
Set sinewave frequencies to generate.
Sets the frequencies of notes to generate based on currently pressed buttons (each button corresponds to a unique note).
buttons | Mask of buttons which are pressed. |
References sinefreqs, sound_get_frequency_from_note(), sound_start_timer(), and sound_stop_timer().
Referenced by play_game(), and record_buttons().
void sound_play_sample | ( | uint8_t | buttons | ) |
Starts playing samples when button status is sent.
Loads information about the sound to play starts the sound timer which triggers conversions and updates of sample value in DAC, at a rate of SOUND_SAMPLE_RATE times per second.
See get_far.h for usage of GET_FAR_ADDRESS(symbol).
buttons | Mask of buttons which are pressed. |
References GET_FAR_ADDRESS, prog_snd_ptr, snd_cnt, snd_len, snd_samplewidth, sound_is_playing(), and sound_start_timer().
Referenced by play_game(), and record_buttons().
uint16_t notes[20] |
Table of frequencies for 20 notes, starting at an A (at 441Hz).
Referenced by sound_get_frequency_from_note().
|
static |
Progmem far flash "pointer".
Pointer to current sample in flash memory. A uint32_t is used for this because avr-gcc is limited to 16 bit pointers – this does not cover memory addresses above 2^16.
Referenced by sample_callback(), and sound_play_sample().
|
static |
Table to contain sinewave frequencies – this is polytonal.
Referenced by sample_callback(), and sound_play_note().
|
static |
Current frame in sound.
Referenced by sample_callback(), sound_is_playing(), and sound_play_sample().
|
static |
Number of frames in a sound.
Referenced by sample_callback(), sound_is_playing(), and sound_play_sample().
|
static |
1 or 2 bytes sample width
Referenced by sample_callback(), and sound_play_sample().