Introduce Rockbox Utility to the manual as automated installation option. Only rather...
[Rockbox.git] / apps / plugins / test_sampr.c
blobd1c9c2ba71a4c60fd51af28b83f80fba052815e2
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 Michael Sevakis
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "plugin.h"
20 #include "oldmenuapi.h"
22 PLUGIN_HEADER
24 struct plugin_api *rb;
26 enum
28 TONE_SINE = 0,
29 TONE_TRIANGLE,
30 TONE_SAWTOOTH,
31 TONE_SQUARE,
32 NUM_WAVEFORMS
35 static int freq = HW_FREQ_DEFAULT;
36 static int waveform = TONE_SINE;
38 /* A441 at 44100Hz. Pitch will change with changing samplerate.
39 Test different waveforms to detect any aliasing in signal which
40 indicates duplicated/dropped samples */
41 static const int16_t A441[NUM_WAVEFORMS][100] =
43 [TONE_SINE] =
45 0, 2057, 4106, 6139, 8148,
46 10125, 12062, 13951, 15785, 17557,
47 19259, 20886, 22430, 23886, 25247,
48 26509, 27666, 28713, 29648, 30465,
49 31163, 31737, 32186, 32508, 32702,
50 32767, 32702, 32508, 32186, 31737,
51 31163, 30465, 29648, 28713, 27666,
52 26509, 25247, 23886, 22430, 20886,
53 19259, 17557, 15785, 13951, 12062,
54 10125, 8148, 6139, 4106, 2057,
55 0, -2057, -4106, -6139, -8148,
56 -10125, -12062, -13951, -15785, -17557,
57 -19259, -20886, -22430, -23886, -25247,
58 -26509, -27666, -28713, -29648, -30465,
59 -31163, -31737, -32186, -32508, -32702,
60 -32767, -32702, -32508, -32186, -31737,
61 -31163, -30465, -29648, -28713, -27666,
62 -26509, -25247, -23886, -22430, -20886,
63 -19259, -17557, -15785, -13951, -12062,
64 -10125, -8148, -6139, -4106, -2057,
66 [TONE_TRIANGLE] =
68 0, 1310, 2621, 3932, 5242,
69 6553, 7864, 9174, 10485, 11796,
70 13106, 14417, 15728, 17038, 18349,
71 19660, 20970, 22281, 23592, 24902,
72 26213, 27524, 28834, 30145, 31456,
73 32767, 31456, 30145, 28834, 27524,
74 26213, 24902, 23592, 22281, 20970,
75 19660, 18349, 17038, 15728, 14417,
76 13106, 11796, 10485, 9174, 7864,
77 6553, 5242, 3932, 2621, 1310,
78 0, -1310, -2621, -3932, -5242,
79 -6553, -7864, -9174, -10485, -11796,
80 -13106, -14417, -15728, -17038, -18349,
81 -19660, -20970, -22281, -23592, -24902,
82 -26213, -27524, -28834, -30145, -31456,
83 -32767, -31456, -30145, -28834, -27524,
84 -26213, -24902, -23592, -22281, -20970,
85 -19660, -18349, -17038, -15728, -14417,
86 -13106, -11796, -10485, -9174, -7864,
87 -6553, -5242, -3932, -2621, -1310,
89 [TONE_SAWTOOTH] =
91 -32767, -32111, -31456, -30800, -30145,
92 -29490, -28834, -28179, -27524, -26868,
93 -26213, -25558, -24902, -24247, -23592,
94 -22936, -22281, -21626, -20970, -20315,
95 -19660, -19004, -18349, -17694, -17038,
96 -16383, -15728, -15072, -14417, -13762,
97 -13106, -12451, -11796, -11140, -10485,
98 -9830, -9174, -8519, -7864, -7208,
99 -6553, -5898, -5242, -4587, -3932,
100 -3276, -2621, -1966, -1310, -655,
101 0, 655, 1310, 1966, 2621,
102 3276, 3932, 4587, 5242, 5898,
103 6553, 7208, 7864, 8519, 9174,
104 9830, 10485, 11140, 11796, 12451,
105 13106, 13762, 14417, 15072, 15728,
106 16383, 17038, 17694, 18349, 19004,
107 19660, 20315, 20970, 21626, 22281,
108 22936, 23592, 24247, 24902, 25558,
109 26213, 26868, 27524, 28179, 28834,
110 29490, 30145, 30800, 31456, 32111,
112 [TONE_SQUARE] =
114 32767, 32767, 32767, 32767, 32767,
115 32767, 32767, 32767, 32767, 32767,
116 32767, 32767, 32767, 32767, 32767,
117 32767, 32767, 32767, 32767, 32767,
118 32767, 32767, 32767, 32767, 32767,
119 32767, 32767, 32767, 32767, 32767,
120 32767, 32767, 32767, 32767, 32767,
121 32767, 32767, 32767, 32767, 32767,
122 32767, 32767, 32767, 32767, 32767,
123 32767, 32767, 32767, 32767, 32767,
124 -32767, -32767, -32767, -32767, -32767,
125 -32767, -32767, -32767, -32767, -32767,
126 -32767, -32767, -32767, -32767, -32767,
127 -32767, -32767, -32767, -32767, -32767,
128 -32767, -32767, -32767, -32767, -32767,
129 -32767, -32767, -32767, -32767, -32767,
130 -32767, -32767, -32767, -32767, -32767,
131 -32767, -32767, -32767, -32767, -32767,
132 -32767, -32767, -32767, -32767, -32767,
133 -32767, -32767, -32767, -32767, -32767,
137 void play_waveform(void)
139 static struct opt_items names[HW_NUM_FREQ] =
141 HW_HAVE_96_([HW_FREQ_96] = { "96kHz", NULL },)
142 HW_HAVE_88_([HW_FREQ_88] = { "88.2kHz", NULL },)
143 HW_HAVE_64_([HW_FREQ_64] = { "64kHz", NULL },)
144 HW_HAVE_48_([HW_FREQ_48] = { "48kHz", NULL },)
145 HW_HAVE_44_([HW_FREQ_44] = { "44.1kHz", NULL },)
146 HW_HAVE_32_([HW_FREQ_32] = { "32kHz", NULL },)
147 HW_HAVE_24_([HW_FREQ_24] = { "24kHz", NULL },)
148 HW_HAVE_22_([HW_FREQ_22] = { "22.05kHz", NULL },)
149 HW_HAVE_16_([HW_FREQ_16] = { "16kHz", NULL },)
150 HW_HAVE_12_([HW_FREQ_12] = { "12kHz", NULL },)
151 HW_HAVE_11_([HW_FREQ_11] = { "11.025kHz", NULL },)
152 HW_HAVE_8_( [HW_FREQ_8 ] = { "8kHz", NULL },)
155 /* 50 cycles of wavform */
156 static int32_t audio[5000];
158 void init_audio(int type)
160 int i;
161 /* Signal amplitudes to adjust for somewhat equal percieved
162 volume */
163 int amps[NUM_WAVEFORMS] =
165 [TONE_SINE] = 8191,
166 [TONE_TRIANGLE] = 5119,
167 [TONE_SAWTOOTH] = 2047,
168 [TONE_SQUARE] = 1535
171 /* Initialize one cycle of the waveform */
172 for (i = 0; i < 100; i++)
174 uint16_t val = amps[type]*A441[type][i]/32767;
175 audio[i] = (val << 16) | val;
178 /* Duplicate it 49 more times */
179 for (i = 1; i < 50; i++)
181 rb->memcpy(audio + i*100, audio, 100*sizeof(int32_t));
185 /* ISR handler to get next block of data */
186 void get_more(unsigned char **start, size_t *size)
188 *start = (unsigned char *)audio;
189 *size = sizeof (audio);
192 /* Called to switch samplerate on the fly */
193 void set_frequency(int index)
195 rb->pcm_set_frequency(rb->hw_freq_sampr[index]);
196 rb->pcm_apply_settings();
199 rb->audio_stop();
200 rb->sound_set(SOUND_VOLUME, rb->sound_default(SOUND_VOLUME));
202 #if INPUT_SRC_CAPS != 0
203 /* Select playback */
204 rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
205 #endif
207 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
208 rb->cpu_boost(true);
209 #endif
211 rb->pcm_set_frequency(rb->hw_freq_sampr[freq]);
213 #if INPUT_SRC_CAPS != 0
214 /* Recordable targets can play back from other sources */
215 rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
216 #endif
218 rb->pcm_apply_settings();
220 init_audio(waveform);
221 rb->pcm_play_data(get_more, NULL, 0);
223 rb->set_option("Sample Rate", &freq, INT, names,
224 HW_NUM_FREQ, set_frequency);
226 rb->pcm_play_stop();
228 while (rb->pcm_is_playing())
229 rb->yield();
231 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
232 rb->cpu_boost(false);
233 #endif
235 /* restore default - user of apis is responsible for restoring
236 default state - normally playback at 44100Hz */
237 rb->pcm_set_frequency(HW_FREQ_DEFAULT);
240 void set_waveform(void)
242 static struct opt_items names[NUM_WAVEFORMS] =
244 [TONE_SINE] = { "Sine", NULL },
245 [TONE_TRIANGLE] = { "Triangle", NULL },
246 [TONE_SAWTOOTH] = { "Sawtooth", NULL },
247 [TONE_SQUARE] = { "Square", NULL },
250 rb->set_option("Waveform", &waveform, INT, names,
251 NUM_WAVEFORMS, NULL);
254 /* Tests hardware sample rate switching */
255 /* TODO: needs a volume control */
256 enum plugin_status plugin_start(struct plugin_api *api, void *parameter)
258 static const struct menu_item items[] =
260 { "Set Waveform", NULL },
261 { "Play Waveform", NULL },
262 { "Quit", NULL },
265 bool exit = false;
266 int m;
267 bool talk_menu;
269 rb = api;
271 /* Have to shut up voice menus or it will mess up our waveform playback */
272 talk_menu = rb->global_settings->talk_menu;
273 rb->global_settings->talk_menu = false;
275 m = menu_init(rb, items, ARRAYLEN(items),
276 NULL, NULL, NULL, NULL);
278 while (!exit)
280 int result = menu_show(m);
282 switch (result)
284 case 0:
285 set_waveform();
286 break;
287 case 1:
288 play_waveform();
289 break;
290 case 2:
291 exit = true;
292 break;
296 menu_exit(m);
298 rb->global_settings->talk_menu = talk_menu;
300 return PLUGIN_OK;
301 (void)parameter;