diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2005-08-20 11:13:19 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2005-08-20 11:13:19 +0000 |
commit | 159c52dd36e5c008612458192904f57ea6dfdfad (patch) | |
tree | 4b6f7d8329069e90d72284ef73ba542d75705b55 /apps/pcmbuf.c | |
parent | 329caa8ade0b78a3235e9d28983cb1c506e573a0 (diff) | |
download | rockbox-159c52dd36e5c008612458192904f57ea6dfdfad.tar.gz rockbox-159c52dd36e5c008612458192904f57ea6dfdfad.zip |
Initial voice ui support for software codec platforms. Added also a
beep when changing tracks.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7360 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r-- | apps/pcmbuf.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 691f8d5a19..5f78901a56 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "buffer.h" | 34 | #include "buffer.h" |
35 | #include "settings.h" | 35 | #include "settings.h" |
36 | #include "audio.h" | 36 | #include "audio.h" |
37 | #include "dsp.h" | ||
37 | 38 | ||
38 | #define CHUNK_SIZE PCMBUF_GUARD | 39 | #define CHUNK_SIZE PCMBUF_GUARD |
39 | /* Must be a power of 2 */ | 40 | /* Must be a power of 2 */ |
@@ -86,9 +87,11 @@ struct pcmbufdesc | |||
86 | volatile int pcmbuf_read_index; | 87 | volatile int pcmbuf_read_index; |
87 | volatile int pcmbuf_write_index; | 88 | volatile int pcmbuf_write_index; |
88 | int pcmbuf_unplayed_bytes; | 89 | int pcmbuf_unplayed_bytes; |
90 | int pcmbuf_mix_used_bytes; | ||
89 | int pcmbuf_watermark; | 91 | int pcmbuf_watermark; |
90 | void (*pcmbuf_watermark_event)(int bytes_left); | 92 | void (*pcmbuf_watermark_event)(int bytes_left); |
91 | static int last_chunksize; | 93 | static int last_chunksize; |
94 | static long mixpos = 0; | ||
92 | 95 | ||
93 | static void pcmbuf_boost(bool state) | 96 | static void pcmbuf_boost(bool state) |
94 | { | 97 | { |
@@ -173,6 +176,7 @@ bool pcmbuf_add_chunk(void *addr, int size, void (*callback)(void)) | |||
173 | pcmbuffers[pcmbuf_write_index].callback = callback; | 176 | pcmbuffers[pcmbuf_write_index].callback = callback; |
174 | pcmbuf_write_index = (pcmbuf_write_index+1) & NUM_PCM_BUFFERS_MASK; | 177 | pcmbuf_write_index = (pcmbuf_write_index+1) & NUM_PCM_BUFFERS_MASK; |
175 | pcmbuf_unplayed_bytes += size; | 178 | pcmbuf_unplayed_bytes += size; |
179 | pcmbuf_mix_used_bytes = MAX(0, pcmbuf_mix_used_bytes - size); | ||
176 | return true; | 180 | return true; |
177 | } | 181 | } |
178 | else | 182 | else |
@@ -254,6 +258,7 @@ void pcmbuf_play_stop(void) | |||
254 | pcm_play_stop(); | 258 | pcm_play_stop(); |
255 | last_chunksize = 0; | 259 | last_chunksize = 0; |
256 | pcmbuf_unplayed_bytes = 0; | 260 | pcmbuf_unplayed_bytes = 0; |
261 | pcmbuf_mix_used_bytes = 0; | ||
257 | pcmbuf_read_index = 0; | 262 | pcmbuf_read_index = 0; |
258 | pcmbuf_write_index = 0; | 263 | pcmbuf_write_index = 0; |
259 | audiobuffer_pos = 0; | 264 | audiobuffer_pos = 0; |
@@ -297,6 +302,13 @@ void pcmbuf_flush_audio(void) | |||
297 | crossfade_init = true; | 302 | crossfade_init = true; |
298 | } | 303 | } |
299 | 304 | ||
305 | /* Force playback. */ | ||
306 | void pcmbuf_play_start(void) | ||
307 | { | ||
308 | if (!pcm_is_playing() && pcmbuf_unplayed_bytes) | ||
309 | pcm_play_data(pcmbuf_callback); | ||
310 | } | ||
311 | |||
300 | void pcmbuf_flush_fillpos(void) | 312 | void pcmbuf_flush_fillpos(void) |
301 | { | 313 | { |
302 | int copy_n; | 314 | int copy_n; |
@@ -562,6 +574,98 @@ bool pcmbuf_insert_buffer(char *buf, long length) | |||
562 | return true; | 574 | return true; |
563 | } | 575 | } |
564 | 576 | ||
577 | /* Generates a constant square wave sound with a given frequency | ||
578 | in Hertz for a duration in milliseconds. */ | ||
579 | void pcmbuf_beep(int frequency, int duration, int amplitude) | ||
580 | { | ||
581 | int state = 0, count = 0; | ||
582 | int interval = NATIVE_FREQUENCY / frequency; | ||
583 | int pos; | ||
584 | short *buf = (short *)audiobuffer; | ||
585 | int bufsize = pcmbuf_size / 2; | ||
586 | |||
587 | /* FIXME: Should start playback. */ | ||
588 | //if (pcmbuf_unplayed_bytes * 1000 < 4 * NATIVE_FREQUENCY * duration) | ||
589 | // return ; | ||
590 | |||
591 | pos = (audiobuffer_pos - pcmbuf_unplayed_bytes) / 2; | ||
592 | if (pos < 0) | ||
593 | pos += bufsize; | ||
594 | |||
595 | duration = NATIVE_FREQUENCY / 1000 * duration; | ||
596 | while (duration-- > 0) | ||
597 | { | ||
598 | if (state) { | ||
599 | buf[pos] = MIN(MAX(buf[pos] + amplitude, -32768), 32767); | ||
600 | if (++pos >= bufsize) | ||
601 | pos = 0; | ||
602 | buf[pos] = MIN(MAX(buf[pos] + amplitude, -32768), 32767); | ||
603 | } else { | ||
604 | buf[pos] = MIN(MAX(buf[pos] - amplitude, -32768), 32767); | ||
605 | if (++pos >= bufsize) | ||
606 | pos = 0; | ||
607 | buf[pos] = MIN(MAX(buf[pos] - amplitude, -32768), 32767); | ||
608 | } | ||
609 | |||
610 | if (++count >= interval) | ||
611 | { | ||
612 | count = 0; | ||
613 | if (state) | ||
614 | state = 0; | ||
615 | else | ||
616 | state = 1; | ||
617 | } | ||
618 | pos++; | ||
619 | if (pos >= bufsize) | ||
620 | pos = 0; | ||
621 | } | ||
622 | } | ||
623 | |||
624 | /* Returns pcm buffer usage in percents (0 to 100). */ | ||
625 | int pcmbuf_usage(void) | ||
626 | { | ||
627 | return pcmbuf_unplayed_bytes * 100 / pcmbuf_size; | ||
628 | } | ||
629 | |||
630 | int pcmbuf_mix_usage(void) | ||
631 | { | ||
632 | return pcmbuf_mix_used_bytes * 100 / pcmbuf_unplayed_bytes; | ||
633 | } | ||
634 | |||
635 | void pcmbuf_reset_mixpos(void) | ||
636 | { | ||
637 | int bufsize = pcmbuf_size / 2; | ||
638 | |||
639 | pcmbuf_mix_used_bytes = 0; | ||
640 | mixpos = (audiobuffer_pos - pcmbuf_unplayed_bytes) / 2; | ||
641 | if (mixpos < 0) | ||
642 | mixpos += bufsize; | ||
643 | if (mixpos >= bufsize) | ||
644 | mixpos -= bufsize; | ||
645 | } | ||
646 | |||
647 | void pcmbuf_mix(char *buf, long length) | ||
648 | { | ||
649 | short *ibuf = (short *)buf; | ||
650 | short *obuf = (short *)audiobuffer; | ||
651 | int bufsize = pcmbuf_size / 2; | ||
652 | |||
653 | if (pcmbuf_mix_used_bytes == 0) | ||
654 | pcmbuf_reset_mixpos(); | ||
655 | |||
656 | pcmbuf_mix_used_bytes += length; | ||
657 | length /= 2; | ||
658 | |||
659 | while (length-- > 0) { | ||
660 | obuf[mixpos] = MIN(MAX(obuf[mixpos] + *ibuf*4, -32768), 32767); | ||
661 | |||
662 | ibuf++; | ||
663 | mixpos++; | ||
664 | if (mixpos >= bufsize) | ||
665 | mixpos = 0; | ||
666 | } | ||
667 | } | ||
668 | |||
565 | void pcmbuf_crossfade_enable(bool on_off) | 669 | void pcmbuf_crossfade_enable(bool on_off) |
566 | { | 670 | { |
567 | crossfade_enabled = on_off; | 671 | crossfade_enabled = on_off; |