annotate foosdk/sdk/foobar2000/shared/audio_math.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "shared.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 //#define AUDIO_MATH_NOASM
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 // NOTE: SSE4.1 int16 ops code determined MUCH SLOWER than SSE2 on Sandy Bridge era Xeon and therefore disabled for now
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 // #define SUPPORT_SSE41
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #ifdef SUPPORT_SSE41
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 static const bool g_have_sse41 = pfc::query_cpu_feature_set(pfc::CPU_HAVE_SSE41);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 inline static void convert_from_int16_noopt(const t_int16 * p_source,t_size p_count,audio_sample * p_output,float p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 t_size num = p_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 for(;num;num--)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 *(p_output++) = (audio_sample)*(p_source++) * p_scale;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 __declspec(naked) static void __fastcall convert_from_int16_sse41_8word(const t_int16 * p_source,t_size p_count,audio_sample * p_output,float p_scale) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 __asm {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 // ecx = source, edx = count, [esp + 4] = output, [esp + 8] = scale
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 movss xmm7, [esp + 8]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 test edx, edx
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 mov eax, [esp + 4]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 pshufd xmm7, xmm7, 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 jz loopend
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 loopbegin:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 PMOVSXWD xmm0, mmword ptr [ecx]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 PMOVSXWD xmm1, mmword ptr [ecx+8]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 CVTDQ2PS xmm0, xmm0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 CVTDQ2PS xmm1, xmm1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 add ecx, 16
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 mulps xmm0, xmm7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 mulps xmm1, xmm7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 dec edx
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 movups [eax], xmm0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 movups [eax + 16], xmm1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 lea eax, [eax + 32]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 jnz loopbegin
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 loopend:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 ret 8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 __declspec(naked) static void __fastcall convert_from_int16_sse41_8word_aligned(const t_int16 * p_source,t_size p_count,audio_sample * p_output,float p_scale) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 __asm {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 // ecx = source, edx = count, [esp + 4] = output, [esp + 8] = scale
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 movss xmm7, [esp + 8]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 test edx, edx
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 mov eax, [esp + 4]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 pshufd xmm7, xmm7, 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 jz loopend
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 loopbegin:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 PMOVSXWD xmm0, mmword ptr [ecx]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 PMOVSXWD xmm1, mmword ptr [ecx+8]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 CVTDQ2PS xmm0, xmm0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 CVTDQ2PS xmm1, xmm1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 add ecx, 16
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 mulps xmm0, xmm7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 mulps xmm1, xmm7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 dec edx
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 movaps [eax], xmm0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 movaps [eax + 16], xmm1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 lea eax, [eax + 32]
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 jnz loopbegin
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 loopend:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 ret 8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 #ifdef audio_math
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 #undef audio_math
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 namespace audio_math {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 void SHARED_EXPORT scale(const audio_sample * p_source,t_size p_count,audio_sample * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 ::pfc::audio_math::scale(p_source, p_count, p_output, p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 void SHARED_EXPORT convert_to_int16(const audio_sample * p_source,t_size p_count,t_int16 * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 ::pfc::audio_math::convert_to_int16(p_source, p_count, p_output, p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 audio_sample SHARED_EXPORT convert_to_int16_calculate_peak(const audio_sample * p_source,t_size p_count,t_int16 * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 convert_to_int16(p_source,p_count,p_output,p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 return p_scale * calculate_peak(p_source,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 void SHARED_EXPORT convert_from_int16(const t_int16 * p_source,t_size p_count,audio_sample * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 #ifdef SUPPORT_SSE41
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 if (g_have_sse41) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 audio_sample scale = (audio_sample)(p_scale / (double)0x8000);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 convert_from_int16_sse41_8word(p_source, p_count >> 3, p_output, scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 convert_from_int16_noopt(p_source + (p_count & ~7), p_count & 7, p_output + (p_count & ~7), scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 ::pfc::audio_math::convert_from_int16(p_source, p_count, p_output, p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 void SHARED_EXPORT convert_to_int32(const audio_sample * p_source,t_size p_count,t_int32 * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 return ::pfc::audio_math::convert_to_int32(p_source, p_count, p_output, p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 audio_sample SHARED_EXPORT convert_to_int32_calculate_peak(const audio_sample * p_source,t_size p_count,t_int32 * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 convert_to_int32(p_source,p_count,p_output,p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 return p_scale * calculate_peak(p_source,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 void SHARED_EXPORT convert_from_int32(const t_int32 * p_source,t_size p_count,audio_sample * p_output,audio_sample p_scale)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 ::pfc::audio_math::convert_from_int32(p_source, p_count, p_output, p_scale);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 audio_sample SHARED_EXPORT calculate_peak(const audio_sample * p_source,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 return ::pfc::audio_math::calculate_peak(p_source, p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 void SHARED_EXPORT kill_denormal(audio_sample * p_buffer,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 ::pfc::audio_math::remove_denormals(p_buffer, p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 void SHARED_EXPORT add_offset(audio_sample * p_buffer,audio_sample p_delta,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 ::pfc::audio_math::add_offset(p_buffer, p_delta, p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 }