summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-11-16 14:26:05 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-11-16 14:26:05 +0000
commit5398125fb30bf4326b29b5a7207ec0a517f09ff0 (patch)
tree1ce592f5cc7c468bb84f1e2a4f8d8bae4cffca2e
parentbbf72baed6438e538097688851c5e98f7c1c6711 (diff)
downloadrockbox-5398125fb30bf4326b29b5a7207ec0a517f09ff0.tar.gz
rockbox-5398125fb30bf4326b29b5a7207ec0a517f09ff0.zip
Use sized data types for audio data in the pcm buffer. Speed up the clipping routine.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15636 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/pcmbuf.c78
1 files changed, 43 insertions, 35 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index a6b82baf25..1a2324baaf 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -42,6 +42,14 @@
42#define PCMBUF_MUTING 42#define PCMBUF_MUTING
43#endif 43#endif
44 44
45/* Clip sample to signed 16 bit range */
46static inline int32_t clip_sample_16(int32_t sample)
47{
48 if ((int16_t)sample != sample)
49 sample = 0x7fff ^ (sample >> 31);
50 return sample;
51}
52
45/* Keep watermark high for iPods at least (2s) */ 53/* Keep watermark high for iPods at least (2s) */
46#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 2) 54#define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 2)
47 55
@@ -564,8 +572,8 @@ static void crossfade_process_buffer(size_t fade_in_delay,
564 while (block_rem > 0 && fade_out_chunk != NULL) 572 while (block_rem > 0 && fade_out_chunk != NULL)
565 { 573 {
566 /* Fade one sample */ 574 /* Fade one sample */
567 short *buf = (short *)(fade_out_chunk->addr); 575 int16_t *buf = (int16_t *)fade_out_chunk->addr;
568 int sample = buf[fade_out_sample]; 576 int32_t sample = buf[fade_out_sample];
569 buf[fade_out_sample++] = (sample * factor) >> 8; 577 buf[fade_out_sample++] = (sample * factor) >> 8;
570 578
571 block_rem -= 2; 579 block_rem -= 2;
@@ -665,16 +673,16 @@ static void crossfade_start(void)
665/* Returns the number of bytes _NOT_ mixed */ 673/* Returns the number of bytes _NOT_ mixed */
666static size_t crossfade_fade_mix(int factor, const char *buf, size_t fade_rem) 674static size_t crossfade_fade_mix(int factor, const char *buf, size_t fade_rem)
667{ 675{
668 const short *input_buf = (const short *)buf; 676 const int16_t *input_buf = (const int16_t *)buf;
669 short *output_buf = (short *)(crossfade_chunk->addr); 677 int16_t *output_buf = (int16_t *)(crossfade_chunk->addr);
670 short *chunk_end = (short *)((size_t)output_buf + crossfade_chunk->size); 678 int16_t *chunk_end = SKIPBYTES(output_buf, crossfade_chunk->size);
671 output_buf = &output_buf[crossfade_sample]; 679 output_buf = &output_buf[crossfade_sample];
672 680
673 while (fade_rem) 681 while (fade_rem)
674 { 682 {
675 int sample = *input_buf++; 683 int sample = *input_buf++;
676 sample = ((sample * factor) >> 8) + *output_buf; 684 sample = ((sample * factor) >> 8) + *output_buf;
677 *output_buf++ = MIN(32767, MAX(-32768, sample)); 685 *output_buf++ = clip_sample_16(sample);
678 fade_rem -= 2; 686 fade_rem -= 2;
679 687
680 if (output_buf >= chunk_end) 688 if (output_buf >= chunk_end)
@@ -682,26 +690,26 @@ static size_t crossfade_fade_mix(int factor, const char *buf, size_t fade_rem)
682 crossfade_chunk = crossfade_chunk->link; 690 crossfade_chunk = crossfade_chunk->link;
683 if (!crossfade_chunk) 691 if (!crossfade_chunk)
684 return fade_rem; 692 return fade_rem;
685 output_buf = (short *)(crossfade_chunk->addr); 693 output_buf = (int16_t *)crossfade_chunk->addr;
686 chunk_end = (short *)((size_t)output_buf + crossfade_chunk->size); 694 chunk_end = SKIPBYTES(output_buf, crossfade_chunk->size);
687 } 695 }
688 } 696 }
689 crossfade_sample = (size_t)(output_buf - (short *)(crossfade_chunk->addr)); 697 crossfade_sample = output_buf - (int16_t *)crossfade_chunk->addr;
690 return 0; 698 return 0;
691} 699}
692 700
693/* Returns the number of bytes _NOT_ mixed */ 701/* Returns the number of bytes _NOT_ mixed */
694static size_t crossfade_mix(const char *buf, size_t length) 702static size_t crossfade_mix(const char *buf, size_t length)
695{ 703{
696 const short *input_buf = (const short *)buf; 704 const int16_t *input_buf = (const int16_t *)buf;
697 short *output_buf = (short *)(crossfade_chunk->addr); 705 int16_t *output_buf = (int16_t *)crossfade_chunk->addr;
698 short *chunk_end = (short *)((size_t)output_buf + crossfade_chunk->size); 706 int16_t *chunk_end = SKIPBYTES(output_buf, crossfade_chunk->size);
699 output_buf = &output_buf[crossfade_sample]; 707 output_buf = &output_buf[crossfade_sample];
700 708
701 while (length) 709 while (length)
702 { 710 {
703 int sample = *input_buf++ + *output_buf; 711 int sample = *input_buf++ + *output_buf;
704 *output_buf++ = MIN(32767, MAX(-32768, sample)); 712 *output_buf++ = clip_sample_16(sample);
705 length -= 2; 713 length -= 2;
706 714
707 if (output_buf >= chunk_end) 715 if (output_buf >= chunk_end)
@@ -709,11 +717,11 @@ static size_t crossfade_mix(const char *buf, size_t length)
709 crossfade_chunk = crossfade_chunk->link; 717 crossfade_chunk = crossfade_chunk->link;
710 if (!crossfade_chunk) 718 if (!crossfade_chunk)
711 return length; 719 return length;
712 output_buf = (short *)(crossfade_chunk->addr); 720 output_buf = (int16_t *)(crossfade_chunk->addr);
713 chunk_end = (short *)((size_t)output_buf + crossfade_chunk->size); 721 chunk_end = SKIPBYTES(output_buf, crossfade_chunk->size);
714 } 722 }
715 } 723 }
716 crossfade_sample = (size_t)(output_buf - (short *)(crossfade_chunk->addr)); 724 crossfade_sample = output_buf - (int16_t *)crossfade_chunk->addr;
717 return 0; 725 return 0;
718} 726}
719 727
@@ -742,7 +750,7 @@ static void flush_crossfade(char *buf, size_t length)
742 if (crossfade_fade_in_rem) 750 if (crossfade_fade_in_rem)
743 { 751 {
744 size_t samples; 752 size_t samples;
745 short *input_buf; 753 int16_t *input_buf;
746 754
747 /* Fade factor for this packet */ 755 /* Fade factor for this packet */
748 int factor = 756 int factor =
@@ -768,11 +776,11 @@ static void flush_crossfade(char *buf, size_t length)
768 } 776 }
769 777
770 samples = fade_rem / 2; 778 samples = fade_rem / 2;
771 input_buf = (short *)buf; 779 input_buf = (int16_t *)buf;
772 /* Fade remaining samples in place */ 780 /* Fade remaining samples in place */
773 while (samples) 781 while (samples)
774 { 782 {
775 int sample = *input_buf; 783 int32_t sample = *input_buf;
776 *input_buf++ = (sample * factor) >> 8; 784 *input_buf++ = (sample * factor) >> 8;
777 samples--; 785 samples--;
778 } 786 }
@@ -940,9 +948,9 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
940{ 948{
941 unsigned int count = 0, i = 0; 949 unsigned int count = 0, i = 0;
942 unsigned int interval = NATIVE_FREQUENCY / frequency; 950 unsigned int interval = NATIVE_FREQUENCY / frequency;
943 long sample; 951 int32_t sample;
944 short *buf; 952 int16_t *buf;
945 short *pcmbuf_end = (short *)fadebuf; 953 int16_t *pcmbuf_end = (int16_t *)fadebuf;
946 size_t samples = NATIVE_FREQUENCY / 1000 * duration; 954 size_t samples = NATIVE_FREQUENCY / 1000 * duration;
947 955
948 if (pcm_is_playing() && pcmbuf_read != NULL) 956 if (pcm_is_playing() && pcmbuf_read != NULL)
@@ -952,7 +960,7 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
952 /* Get the next chunk */ 960 /* Get the next chunk */
953 char *pcmbuf_mix_buf = pcmbuf_read->link->addr; 961 char *pcmbuf_mix_buf = pcmbuf_read->link->addr;
954 /* Give at least 1/8s clearance. */ 962 /* Give at least 1/8s clearance. */
955 buf = (short *)&pcmbuf_mix_buf[NATIVE_FREQUENCY * 4 / 8]; 963 buf = (int16_t *)&pcmbuf_mix_buf[NATIVE_FREQUENCY * 4 / 8];
956 } 964 }
957 else 965 else
958 { 966 {
@@ -963,11 +971,11 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
963 while (i++ < samples) 971 while (i++ < samples)
964 { 972 {
965 sample = *buf; 973 sample = *buf;
966 *buf++ = MIN(MAX(sample + amplitude, -32768), 32767); 974 *buf++ = clip_sample_16(sample + amplitude);
967 if (buf > pcmbuf_end) 975 if (buf > pcmbuf_end)
968 buf = (short *)audiobuffer; 976 buf = (int16_t *)audiobuffer;
969 sample = *buf; 977 sample = *buf;
970 *buf++ = MIN(MAX(sample + amplitude, -32768), 32767); 978 *buf++ = clip_sample_16(sample + amplitude);
971 979
972 /* Toggle square wav side */ 980 /* Toggle square wav side */
973 if (++count >= interval) 981 if (++count >= interval)
@@ -976,17 +984,17 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
976 amplitude = -amplitude; 984 amplitude = -amplitude;
977 } 985 }
978 if (buf > pcmbuf_end) 986 if (buf > pcmbuf_end)
979 buf = (short *)audiobuffer; 987 buf = (int16_t *)audiobuffer;
980 } 988 }
981 } 989 }
982 else 990 else
983 { 991 {
984 buf = (short *)audiobuffer; 992 buf = (int16_t *)audiobuffer;
985 while (i++ < samples) 993 while (i++ < samples)
986 { 994 {
987 *buf++ = amplitude; 995 *buf++ = amplitude;
988 if (buf > pcmbuf_end) 996 if (buf > pcmbuf_end)
989 buf = (short *)audiobuffer; 997 buf = (int16_t *)audiobuffer;
990 *buf++ = amplitude; 998 *buf++ = amplitude;
991 999
992 /* Toggle square wav side */ 1000 /* Toggle square wav side */
@@ -996,7 +1004,7 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
996 amplitude = -amplitude; 1004 amplitude = -amplitude;
997 } 1005 }
998 if (buf > pcmbuf_end) 1006 if (buf > pcmbuf_end)
999 buf = (short *)audiobuffer; 1007 buf = (int16_t *)audiobuffer;
1000 } 1008 }
1001 pcm_play_data(NULL, (unsigned char *)audiobuffer, samples * 4); 1009 pcm_play_data(NULL, (unsigned char *)audiobuffer, samples * 4);
1002 } 1010 }
@@ -1013,7 +1021,7 @@ int pcmbuf_mix_free(void)
1013 if (pcmbuf_mix_chunk) 1021 if (pcmbuf_mix_chunk)
1014 { 1022 {
1015 size_t my_mix_end = 1023 size_t my_mix_end =
1016 (size_t)&((short *)pcmbuf_mix_chunk->addr)[pcmbuf_mix_sample]; 1024 (size_t)&((int16_t *)pcmbuf_mix_chunk->addr)[pcmbuf_mix_sample];
1017 size_t my_write_pos = (size_t)&audiobuffer[audiobuffer_pos]; 1025 size_t my_write_pos = (size_t)&audiobuffer[audiobuffer_pos];
1018 if (my_write_pos < my_mix_end) 1026 if (my_write_pos < my_mix_end)
1019 my_write_pos += pcmbuf_size; 1027 my_write_pos += pcmbuf_size;
@@ -1024,8 +1032,8 @@ int pcmbuf_mix_free(void)
1024 1032
1025void pcmbuf_mix_voice(int count) 1033void pcmbuf_mix_voice(int count)
1026{ 1034{
1027 short *ibuf = (short *)voicebuf; 1035 int16_t *ibuf = (int16_t *)voicebuf;
1028 short *obuf; 1036 int16_t *obuf;
1029 size_t chunk_samples; 1037 size_t chunk_samples;
1030 1038
1031 if (pcmbuf_mix_chunk == NULL && pcmbuf_read != NULL) 1039 if (pcmbuf_mix_chunk == NULL && pcmbuf_read != NULL)
@@ -1037,7 +1045,7 @@ void pcmbuf_mix_voice(int count)
1037 if (!pcmbuf_mix_chunk) 1045 if (!pcmbuf_mix_chunk)
1038 return; 1046 return;
1039 1047
1040 obuf = (short *)pcmbuf_mix_chunk->addr; 1048 obuf = (int16_t *)pcmbuf_mix_chunk->addr;
1041 chunk_samples = pcmbuf_mix_chunk->size / 2; 1049 chunk_samples = pcmbuf_mix_chunk->size / 2;
1042 1050
1043 count <<= 1; 1051 count <<= 1;
@@ -1054,7 +1062,7 @@ void pcmbuf_mix_voice(int count)
1054 chunk_samples = pcmbuf_mix_chunk->size / 2; 1062 chunk_samples = pcmbuf_mix_chunk->size / 2;
1055 } 1063 }
1056 sample += obuf[pcmbuf_mix_sample] >> 2; 1064 sample += obuf[pcmbuf_mix_sample] >> 2;
1057 obuf[pcmbuf_mix_sample++] = MIN(MAX(sample, -32768), 32767); 1065 obuf[pcmbuf_mix_sample++] = clip_sample_16(sample);
1058 } 1066 }
1059} 1067}
1060 1068