1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (c) 2011 Michael Sevakis
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "dsp_core.h" /* for NATIVE_FREQUENCY */
26 #include "pcm_mixer.h"
29 /** Beep generation, CPU optimized **/
32 static uint32_t beep_phase
; /* Phase of square wave generator */
33 static uint32_t beep_step
; /* Step of square wave generator on each sample */
35 static int16_t beep_amplitude
; /* Amplitude of square wave generator */
37 /* Optimized routines do XOR with phase sign bit in both channels at once */
38 static uint32_t beep_amplitude
; /* Amplitude of square wave generator */
40 static int beep_count
; /* Number of samples remaining to generate */
42 /* Reserve enough static space for keyclick to fit */
43 #define BEEP_BUF_COUNT (NATIVE_FREQUENCY / 1000 * KEYCLICK_DURATION)
44 static int16_t beep_buf
[BEEP_BUF_COUNT
*2] IBSS_ATTR
__attribute__((aligned(4)));
46 /* Callback to generate the beep frames - also don't want inlining of
47 call below in beep_play */
48 static void __attribute__((noinline
))
49 beep_get_more(const void **start
, size_t *size
)
51 int count
= beep_count
;
55 count
= MIN(count
, BEEP_BUF_COUNT
);
58 *size
= count
* 2 * sizeof (int16_t);
59 beep_generate((void *)beep_buf
, count
, &beep_phase
,
60 beep_step
, beep_amplitude
);
64 /* Generates a constant square wave sound with a given frequency in Hertz for
65 a duration in milliseconds */
66 void beep_play(unsigned int frequency
, unsigned int duration
,
67 unsigned int amplitude
)
69 mixer_channel_stop(PCM_MIXER_CHAN_BEEP
);
71 if (frequency
== 0 || duration
== 0 || amplitude
== 0)
74 if (amplitude
> INT16_MAX
)
75 amplitude
= INT16_MAX
;
77 /* Setup the parameters for the square wave generator */
79 beep_step
= 0xffffffffu
/ NATIVE_FREQUENCY
* frequency
;
80 beep_count
= NATIVE_FREQUENCY
/ 1000 * duration
;
83 beep_amplitude
= amplitude
;
85 /* Optimized routines do XOR with phase sign bit in both channels at once */
86 beep_amplitude
= amplitude
| (amplitude
<< 16); /* Word:|AMP16|AMP16| */
89 /* If it fits - avoid cb overhead */
93 /* Generate first frame here */
94 beep_get_more(&start
, &size
);
96 mixer_channel_set_amplitude(PCM_MIXER_CHAN_BEEP
, MIX_AMP_UNITY
);
97 mixer_channel_play_data(PCM_MIXER_CHAN_BEEP
,
98 beep_count
? beep_get_more
: NULL
,