diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-01-16 14:15:22 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-01-17 00:37:12 +0000 |
commit | 525eb158643055bd5a652e824ee2db547a323504 (patch) | |
tree | b324fe7a3aa99e9f317d52aceaa6d448c8117872 /apps | |
parent | f68c6c14d9523b45d67d39cd97e40a44e9932c95 (diff) | |
download | rockbox-525eb158643055bd5a652e824ee2db547a323504.tar.gz rockbox-525eb158643055bd5a652e824ee2db547a323504.zip |
recording: fix mono mode mixdown functions
Rewrite copy_buffer_mono_* functions for correctness.
Bad pointer arithmetic in copy_buffer_mono_l produced
wrong results, or panics on archs which can't handle
the unaligned pointer.
None of the functions handled zero size copies properly
though this probably wasn't an issue in practice.
Change-Id: I81c894e1b8a3440cb409092bec07fe3778a78959
Diffstat (limited to 'apps')
-rw-r--r-- | apps/recorder/pcm_record.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index 9b0e779485..ef10f8a433 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c | |||
@@ -878,53 +878,37 @@ copy_buffer_mono_lr(void *dst, const void *src, size_t src_size) | |||
878 | ssize_t copy_size = src_size; | 878 | ssize_t copy_size = src_size; |
879 | 879 | ||
880 | /* mono = (L + R) / 2 */ | 880 | /* mono = (L + R) / 2 */ |
881 | do | 881 | while(copy_size > 0) { |
882 | { | 882 | *d++ = ((int32_t)s[0] + (int32_t)s[1] + 1) >> 1; |
883 | *d++ = ((int32_t){s[0]} + s[1] + 1) >> 1; | 883 | s += 2; |
884 | s+=2; | 884 | copy_size -= PCM_SAMP_SIZE; |
885 | } | 885 | } |
886 | while ((copy_size -= PCM_SAMP_SIZE) > 0); | ||
887 | 886 | ||
888 | return dst; | 887 | return dst; |
889 | } | 888 | } |
890 | 889 | ||
891 | /* Copy with mono conversion - output 1/2 size of input */ | ||
892 | static void * ICODE_ATTR | 890 | static void * ICODE_ATTR |
893 | copy_buffer_mono_r(void *dst, const void *src, size_t src_size) | 891 | copy_buffer_mono_l(void *dst, const void *src, size_t src_size) |
894 | { | 892 | { |
895 | int16_t *d = (int16_t*)dst; | 893 | int16_t *d = (int16_t*) dst; |
896 | int16_t const *s = (int16_t const*)src - 1; | 894 | int16_t const *s = (int16_t const*) src; |
897 | ssize_t copy_size = src_size; | 895 | ssize_t copy_size = src_size; |
898 | /* mono = R */ | 896 | |
899 | do | 897 | /* mono = L */ |
900 | *d++ = *(s += 2); | 898 | while(copy_size > 0) { |
901 | while ((copy_size -= PCM_SAMP_SIZE) > 0); | 899 | *d++ = *s; |
900 | s += 2; | ||
901 | copy_size -= PCM_SAMP_SIZE; | ||
902 | } | ||
902 | 903 | ||
903 | return dst; | 904 | return dst; |
904 | } | 905 | } |
905 | 906 | ||
906 | #if 1 | ||
907 | static void * ICODE_ATTR | ||
908 | copy_buffer_mono_l(void *dst, const void *src, size_t src_size) | ||
909 | { | ||
910 | return copy_buffer_mono_r(dst, src -1, src_size); | ||
911 | } | ||
912 | #else | ||
913 | /* Copy with mono conversion - output 1/2 size of input */ | ||
914 | static void * ICODE_ATTR | 907 | static void * ICODE_ATTR |
915 | copy_buffer_mono_l(void *dst, const void *src, size_t src_size) | 908 | copy_buffer_mono_r(void *dst, const void *src, size_t src_size) |
916 | { | 909 | { |
917 | int16_t *d = (int16_t*)dst; | 910 | return copy_buffer_mono_l(dst, src + 2, src_size); |
918 | int16_t const *s = (int16_t const*)src - 2; | ||
919 | ssize_t copy_size = src_size; | ||
920 | /* mono = L */ | ||
921 | do | ||
922 | *d++ = *(s += 2); | ||
923 | while ((copy_size -= PCM_SAMP_SIZE) > 0); | ||
924 | |||
925 | return dst; | ||
926 | } | 911 | } |
927 | #endif | ||
928 | 912 | ||
929 | 913 | ||
930 | /** pcm_rec_* group **/ | 914 | /** pcm_rec_* group **/ |