-
Notifications
You must be signed in to change notification settings - Fork 0
/
audio_asm.s
177 lines (171 loc) · 3.47 KB
/
audio_asm.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;
; MyPod - dsPIC Based MP3 Player
; Copyright (C) 2014 Fernando Rodriguez (support@fernansoft.com)
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License Version 3 as
; published by the Free Software Foundation.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;
;
; void truncate(int* samples, int att_ratio, n_samples, dither);
;
; w0 - 16-bit samples buffer
; w1 - attenuation ratio in Q15 format
; w2 - sample count
;
.text
.global _truncate
_truncate:
push w9
;
; initialize registers
;
mov w0, w9 ; pointer for x memory prefetch
mov w1, w7 ; attenuation ratio
dec w2, w2 ; for hardware do...loop
mov [w9++], w5 ; fetch 1st sample
mov #127, w4 ; for signed->unsigned conv
;mov #32767, w5
clr b
;
; truncate samples
;
do w2, _quant16_loop
mpy w5 * w7, a;, [w9] += 2, w5 ; attenuate sample
mov [w9++], w5
add a
sftac a, #8 ; truncate to 8-bits
clr b
add b
sac a, w2
neg w2, w2
add w2, b
;
; write back as 8 bit unsigned and
; fetch the next sample
;
add w4, a ; convert to unsigned
_quant16_loop:
sac a, [w0++] ; write back to buffer
;
; unstack registers and return
;
pop w9
return
;
; void truncate(int* samples, int att_ratio, n_samples, dither);
;
; w0:w1 - 16-bit samples buffer
; w2 - attenuation ratio in Q15 format
; w3 - sample count
;
.equ USE_PREFETCH, 1
.text
.global _truncate_eds
.ifdef USE_PREFETCH
_truncate_eds:
push w11
;push DSRPAG
push DSWPAG
;
; set paging registers
;
btss w0, #15
inc w1, w1
;mov w1, DSRPAG
mov w1, DSWPAG
;
; initialize registers
;
mov w0, w11 ; pointer for y memory prefetch
mov w2, w7 ; attenuation ratio
dec w3, w3 ; for hardware do...loop
movsac a, [w11] += 2, w5 ; fetch 1st sample
mov #128, w4 ; for signed->unsigned conv
;mov #32767, w5
clr b
;
; truncate samples
;
do w3, _quant16_loop_eds
mpy w5 * w7, a, [w11] += 2, w5 ; attenuate sample
add a
sftac a, #8 ; truncate to 8-bits
clr b
add b
sac a, w3
neg w3, w3
add w3, b
;
; write back as 8 bit unsigned and
; fetch the next sample
;
add w4, a ; convert to unsigned
_quant16_loop_eds:
sac a, [w0++] ; write back to buffer
;
; unstack registers and return
;
pop DSWPAG
;pop DSRPAG
pop w9
return
.else
_truncate_eds:
push w9
push DSRPAG
push DSWPAG
;
; set paging registers
;
btss w0, #15
inc w1, w1
mov w1, DSRPAG
mov w1, DSWPAG
;
; initialize registers
;
mov w0, w9 ; pointer for y memory prefetch
mov w2, w7 ; attenuation ratio
dec w3, w3 ; for hardware do...loop
mov [w9++], w5 ; fetch 1st sample
mov #128, w4 ; for signed->unsigned conv
;mov #32767, w5
clr b
;
; truncate samples
;
do w3, _quant16_loop_eds
mpy w5 * w7, a;, [w9] += 2, w5 ; attenuate sample
add a
sftac a, #7 ; truncate to 8-bits
clr b
add b
sac a, w3
neg w3, w3
add w3, b
;
; write back as 8 bit unsigned and
; fetch the next sample
;
add w4, a ; convert to unsigned
mov [w9++], w5
_quant16_loop_eds:
sac a, [w0++] ; write back to buffer
;
; unstack registers and return
;
pop DSWPAG
pop DSRPAG
pop w9
return
.endif