diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-11-16 14:26:05 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-11-16 14:26:05 +0000 |
commit | 5398125fb30bf4326b29b5a7207ec0a517f09ff0 (patch) | |
tree | 1ce592f5cc7c468bb84f1e2a4f8d8bae4cffca2e | |
parent | bbf72baed6438e538097688851c5e98f7c1c6711 (diff) | |
download | rockbox-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.c | 78 |
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 */ | ||
46 | static 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 */ |
666 | static size_t crossfade_fade_mix(int factor, const char *buf, size_t fade_rem) | 674 | static 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 */ |
694 | static size_t crossfade_mix(const char *buf, size_t length) | 702 | static 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 | ||
1025 | void pcmbuf_mix_voice(int count) | 1033 | void 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 | ||