summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Low <lostlogic@rockbox.org>2006-02-22 01:56:44 +0000
committerBrandon Low <lostlogic@rockbox.org>2006-02-22 01:56:44 +0000
commit9535a9a6390ca51b11d13a8dd338432c466f4477 (patch)
treef42602ea43e1c2d0e196fd293ac7561bcccfe6d8
parenta13f8471863e868a2d744baac4a5f5b20b3fa842 (diff)
downloadrockbox-9535a9a6390ca51b11d13a8dd338432c466f4477.tar.gz
rockbox-9535a9a6390ca51b11d13a8dd338432c466f4477.zip
Fix some of the voice and beep bugs that people have noticed since my new pcmbuf code went in, reduce code duplication, and improve performance while I'm at it
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8775 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/pcmbuf.c105
-rw-r--r--apps/pcmbuf.h3
2 files changed, 53 insertions, 55 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index c79b0d5fd9..31b59f88f6 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -97,7 +97,7 @@ static size_t last_chunksize IDATA_ATTR;
97static size_t pcmbuf_unplayed_bytes IDATA_ATTR; 97static size_t pcmbuf_unplayed_bytes IDATA_ATTR;
98static size_t pcmbuf_mix_used_bytes IDATA_ATTR; 98static size_t pcmbuf_mix_used_bytes IDATA_ATTR;
99static size_t pcmbuf_watermark IDATA_ATTR; 99static size_t pcmbuf_watermark IDATA_ATTR;
100static size_t mixpos IDATA_ATTR = 0; 100static short *mixpos IDATA_ATTR;
101static bool low_latency_mode = false; 101static bool low_latency_mode = false;
102 102
103/* Helpful macros for use in conditionals this assumes some of the above 103/* Helpful macros for use in conditionals this assumes some of the above
@@ -805,13 +805,6 @@ void pcmbuf_write_complete(size_t length)
805 } 805 }
806} 806}
807 807
808void pcmbuf_write_voice(size_t length)
809{
810 while (pcm_is_playing())
811 sleep(1);
812 pcm_play_data(NULL, &guardbuf[0], length);
813}
814
815bool pcmbuf_insert_buffer(const char *buf, size_t length) 808bool pcmbuf_insert_buffer(const char *buf, size_t length)
816{ 809{
817 if (!prepare_insert(length)) 810 if (!prepare_insert(length))
@@ -827,52 +820,63 @@ bool pcmbuf_insert_buffer(const char *buf, size_t length)
827 return true; 820 return true;
828} 821}
829 822
823/* Get a pointer to where to mix immediate audio */
824static inline short* get_mix_insert_pos(void) {
825 /* Give at least 1/8s clearance here */
826 size_t pcmbuf_mix_back_pos =
827 pcmbuf_unplayed_bytes - NATIVE_FREQUENCY * 4 / 8;
828
829 if (audiobuffer_pos < pcmbuf_mix_back_pos)
830 return (short *)&audiobuffer[pcmbuf_size +
831 audiobuffer_pos - pcmbuf_mix_back_pos];
832 else
833 return (short *)&audiobuffer[audiobuffer_pos - pcmbuf_mix_back_pos];
834}
835
830/* Generates a constant square wave sound with a given frequency 836/* Generates a constant square wave sound with a given frequency
831 in Hertz for a duration in milliseconds. */ 837 in Hertz for a duration in milliseconds. */
832void pcmbuf_beep(int frequency, int duration, int amplitude) 838void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
833{ 839{
834 unsigned int state = 0, count = 0; 840 unsigned int count = 0, i = 0;
841 bool state = false;
835 unsigned int interval = NATIVE_FREQUENCY / frequency; 842 unsigned int interval = NATIVE_FREQUENCY / frequency;
836 size_t pos; 843 short *buf;
837 short *buf = (short *)audiobuffer; 844 short *pcmbuf_end = (short *)guardbuf;
838 size_t bufsize = pcmbuf_size / 2; 845 bool playing = pcm_is_playing();
846 size_t samples = NATIVE_FREQUENCY / 1000 * duration;
839 847
840 /* FIXME: Should start playback. */ 848 if (playing) {
841 //if (pcmbuf_unplayed_bytes * 1000 < 4 * NATIVE_FREQUENCY * duration) 849 buf = get_mix_insert_pos();
842 // return ; 850 } else {
843 851 buf = (short *)audiobuffer;
844 if (audiobuffer_pos < pcmbuf_unplayed_bytes) 852 }
845 pos = pcmbuf_size + audiobuffer_pos - pcmbuf_unplayed_bytes; 853 while (i++ < samples)
846 else
847 pos = audiobuffer_pos - pcmbuf_unplayed_bytes;
848 pos /= 2;
849
850 duration = NATIVE_FREQUENCY / 1000 * duration;
851 while (duration-- > 0)
852 { 854 {
855 long sample = *buf;
853 if (state) { 856 if (state) {
854 buf[pos] = MIN(MAX(buf[pos] + amplitude, -32768), 32767); 857 *buf++ = MIN(MAX(sample + amplitude, -32768), 32767);
855 if (++pos >= bufsize) 858 if (buf > pcmbuf_end)
856 pos = 0; 859 buf = (short *)audiobuffer;
857 buf[pos] = MIN(MAX(buf[pos] + amplitude, -32768), 32767); 860 sample = *buf;
861 *buf++ = MIN(MAX(sample + amplitude, -32768), 32767);
858 } else { 862 } else {
859 buf[pos] = MIN(MAX(buf[pos] - amplitude, -32768), 32767); 863 *buf++ = MIN(MAX(sample - amplitude, -32768), 32767);
860 if (++pos >= bufsize) 864 if (buf > pcmbuf_end)
861 pos = 0; 865 buf = (short *)audiobuffer;
862 buf[pos] = MIN(MAX(buf[pos] - amplitude, -32768), 32767); 866 sample = *buf;
867 *buf++ = MIN(MAX(sample - amplitude, -32768), 32767);
863 } 868 }
864 869
865 if (++count >= interval) 870 if (++count >= interval)
866 { 871 {
867 count = 0; 872 count = 0;
868 if (state) 873 state = !state;
869 state = 0;
870 else
871 state = 1;
872 } 874 }
873 pos++; 875 if (buf > pcmbuf_end)
874 if (pos >= bufsize) 876 buf = (short *)audiobuffer;
875 pos = 0; 877 }
878 if (!playing) {
879 pcm_play_data(NULL, (unsigned char *)audiobuffer, samples * 4);
876 } 880 }
877} 881}
878 882
@@ -889,19 +893,14 @@ int pcmbuf_mix_usage(void)
889 893
890void pcmbuf_reset_mixpos(void) 894void pcmbuf_reset_mixpos(void)
891{ 895{
896 mixpos = get_mix_insert_pos();
892 pcmbuf_mix_used_bytes = 0; 897 pcmbuf_mix_used_bytes = 0;
893 if (audiobuffer_pos < pcmbuf_unplayed_bytes)
894 mixpos = pcmbuf_size + audiobuffer_pos - pcmbuf_unplayed_bytes;
895 else
896 mixpos = audiobuffer_pos - pcmbuf_unplayed_bytes;
897 mixpos /= 2;
898} 898}
899 899
900void pcmbuf_mix(char *buf, size_t length) 900void pcmbuf_mix(char *buf, size_t length)
901{ 901{
902 short *ibuf = (short *)buf; 902 short *ibuf = (short *)buf;
903 short *obuf = (short *)audiobuffer; 903 short *pcmbuf_end = (short *)guardbuf;
904 size_t bufsize = pcmbuf_size / 2;
905 904
906 if (pcmbuf_mix_used_bytes == 0) 905 if (pcmbuf_mix_used_bytes == 0)
907 pcmbuf_reset_mixpos(); 906 pcmbuf_reset_mixpos();
@@ -910,12 +909,12 @@ void pcmbuf_mix(char *buf, size_t length)
910 length /= 2; 909 length /= 2;
911 910
912 while (length-- > 0) { 911 while (length-- > 0) {
913 obuf[mixpos] = MIN(MAX(obuf[mixpos]/4 + *ibuf, -32768), 32767); 912 long sample = *ibuf++;
914 913 sample += *mixpos >> 2;
915 ibuf++; 914 *mixpos++ = MIN(MAX(sample, -32768), 32767);
916 mixpos++; 915
917 if (mixpos >= bufsize) 916 if (mixpos >= pcmbuf_end)
918 mixpos = 0; 917 mixpos = (short *)audiobuffer;
919 } 918 }
920} 919}
921 920
diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h
index 555c1bcb33..b659e8fa4e 100644
--- a/apps/pcmbuf.h
+++ b/apps/pcmbuf.h
@@ -58,7 +58,6 @@ unsigned int pcmbuf_get_latency(void);
58void pcmbuf_set_low_latency(bool state); 58void pcmbuf_set_low_latency(bool state);
59bool pcmbuf_insert_buffer(const char *buf, size_t length); 59bool pcmbuf_insert_buffer(const char *buf, size_t length);
60void pcmbuf_write_complete(size_t length); 60void pcmbuf_write_complete(size_t length);
61void pcmbuf_write_voice(size_t length);
62void* pcmbuf_request_buffer(size_t length, size_t *realsize); 61void* pcmbuf_request_buffer(size_t length, size_t *realsize);
63void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix); 62void* pcmbuf_request_voice_buffer(size_t length, size_t *realsize, bool mix);
64bool pcmbuf_is_crossfade_enabled(void); 63bool pcmbuf_is_crossfade_enabled(void);
@@ -66,7 +65,7 @@ void pcmbuf_crossfade_enable(bool on_off);
66 65
67int pcmbuf_usage(void); 66int pcmbuf_usage(void);
68int pcmbuf_mix_usage(void); 67int pcmbuf_mix_usage(void);
69void pcmbuf_beep(int frequency, int duration, int amplitude); 68void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude);
70void pcmbuf_reset_mixpos(void); 69void pcmbuf_reset_mixpos(void);
71void pcmbuf_mix(char *buf, size_t length); 70void pcmbuf_mix(char *buf, size_t length);
72 71