summaryrefslogtreecommitdiff
path: root/apps/recorder/pcm_record.c
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-01-16 14:15:22 +0000
committerAidan MacDonald <amachronic@protonmail.com>2022-01-17 00:37:12 +0000
commit525eb158643055bd5a652e824ee2db547a323504 (patch)
treeb324fe7a3aa99e9f317d52aceaa6d448c8117872 /apps/recorder/pcm_record.c
parentf68c6c14d9523b45d67d39cd97e40a44e9932c95 (diff)
downloadrockbox-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/recorder/pcm_record.c')
-rw-r--r--apps/recorder/pcm_record.c48
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 */
892static void * ICODE_ATTR 890static void * ICODE_ATTR
893copy_buffer_mono_r(void *dst, const void *src, size_t src_size) 891copy_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
907static void * ICODE_ATTR
908copy_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 */
914static void * ICODE_ATTR 907static void * ICODE_ATTR
915copy_buffer_mono_l(void *dst, const void *src, size_t src_size) 908copy_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 **/