@@ -49,92 +49,74 @@ void audio_dma_reset(void) {
49
49
}
50
50
51
51
52
- STATIC void audio_dma_convert_samples (
53
- audio_dma_t * dma ,
54
- uint8_t * input , uint32_t input_length ,
55
- uint8_t * available_output_buffer , uint32_t available_output_buffer_length ,
56
- uint8_t * * output , uint32_t * output_length ) {
57
-
52
+ STATIC size_t audio_dma_convert_samples (audio_dma_t * dma , uint8_t * input , uint32_t input_length , uint8_t * output , uint32_t output_length ) {
58
53
#pragma GCC diagnostic push
59
54
#pragma GCC diagnostic ignored "-Wcast-align"
60
55
61
- // Check whether a conversion is necessary
62
- if (dma -> signed_to_unsigned ||
63
- dma -> unsigned_to_signed ||
64
- dma -> sample_spacing > 1 ||
65
- (dma -> sample_resolution != dma -> output_resolution )) {
56
+ uint32_t output_length_used = input_length / dma -> sample_spacing ;
66
57
67
- // Must convert.
68
- // Write the conversion into the passed-in output buffer
69
- * output = available_output_buffer ;
70
- * output_length = input_length / dma -> sample_spacing ;
58
+ if (output_length_used > output_length ) {
59
+ mp_raise_RuntimeError (translate ("Internal audio buffer too small" ));
60
+ }
71
61
72
- if (* output_length > available_output_buffer_length ) {
62
+ uint32_t out_i = 0 ;
63
+ if (dma -> sample_resolution <= 8 && dma -> output_resolution > 8 ) {
64
+ // reading bytes, writing 16-bit words, so output buffer will be bigger.
65
+
66
+ output_length_used = output_length * 2 ;
67
+ if (output_length_used > output_length ) {
73
68
mp_raise_RuntimeError (translate ("Internal audio buffer too small" ));
74
69
}
75
70
76
- uint32_t out_i = 0 ;
77
- if (dma -> sample_resolution <= 8 && dma -> output_resolution > 8 ) {
78
- // reading bytes, writing 16-bit words, so output buffer will be bigger.
71
+ size_t shift = dma -> output_resolution - dma -> sample_resolution ;
79
72
80
- * output_length = * output_length * 2 ;
81
- if (* output_length > available_output_buffer_length ) {
82
- mp_raise_RuntimeError (translate ("Internal audio buffer too small" ));
73
+ for (uint32_t i = 0 ; i < input_length ; i += dma -> sample_spacing ) {
74
+ if (dma -> signed_to_unsigned ) {
75
+ ((uint16_t * )output )[out_i ] = ((uint16_t )((int8_t * )input )[i ] + 0x80 ) << shift ;
76
+ } else if (dma -> unsigned_to_signed ) {
77
+ ((int16_t * )output )[out_i ] = ((int16_t )((uint8_t * )input )[i ] - 0x80 ) << shift ;
78
+ } else {
79
+ ((uint16_t * )output )[out_i ] = ((uint16_t )((uint8_t * )input )[i ]) << shift ;
83
80
}
84
-
85
- size_t shift = dma -> output_resolution - dma -> sample_resolution ;
86
-
87
- for (uint32_t i = 0 ; i < input_length ; i += dma -> sample_spacing ) {
88
- if (dma -> signed_to_unsigned ) {
89
- ((uint16_t * )* output )[out_i ] = ((uint16_t )((int8_t * )input )[i ] + 0x80 ) << shift ;
90
- } else if (dma -> unsigned_to_signed ) {
91
- ((int16_t * )* output )[out_i ] = ((int16_t )((uint8_t * )input )[i ] - 0x80 ) << shift ;
92
- } else {
93
- ((uint16_t * )* output )[out_i ] = ((uint16_t )((uint8_t * )input )[i ]) << shift ;
94
- }
95
- out_i += 1 ;
81
+ out_i += 1 ;
82
+ }
83
+ } else if (dma -> sample_resolution <= 8 && dma -> output_resolution <= 8 ) {
84
+ for (uint32_t i = 0 ; i < input_length ; i += dma -> sample_spacing ) {
85
+ if (dma -> signed_to_unsigned ) {
86
+ ((uint8_t * )output )[out_i ] = ((int8_t * )input )[i ] + 0x80 ;
87
+ } else if (dma -> unsigned_to_signed ) {
88
+ ((int8_t * )output )[out_i ] = ((uint8_t * )input )[i ] - 0x80 ;
89
+ } else {
90
+ ((uint8_t * )output )[out_i ] = ((uint8_t * )input )[i ];
96
91
}
97
- } else if (dma -> sample_resolution <= 8 && dma -> output_resolution <= 8 ) {
98
- for (uint32_t i = 0 ; i < input_length ; i += dma -> sample_spacing ) {
99
- if (dma -> signed_to_unsigned ) {
100
- ((uint8_t * )* output )[out_i ] = ((int8_t * )input )[i ] + 0x80 ;
101
- } else if (dma -> unsigned_to_signed ) {
102
- ((int8_t * )* output )[out_i ] = ((uint8_t * )input )[i ] - 0x80 ;
103
- } else {
104
- ((uint8_t * )* output )[out_i ] = ((uint8_t * )input )[i ];
105
- }
106
- out_i += 1 ;
92
+ out_i += 1 ;
93
+ }
94
+ } else if (dma -> sample_resolution > 8 && dma -> output_resolution > 8 ) {
95
+ size_t shift = 16 - dma -> output_resolution ;
96
+ for (uint32_t i = 0 ; i < input_length / 2 ; i += dma -> sample_spacing ) {
97
+ if (dma -> signed_to_unsigned ) {
98
+ ((uint16_t * )output )[out_i ] = ((int16_t * )input )[i ] + 0x8000 ;
99
+ } else if (dma -> unsigned_to_signed ) {
100
+ ((int16_t * )output )[out_i ] = ((uint16_t * )input )[i ] - 0x8000 ;
101
+ } else {
102
+ ((uint16_t * )output )[out_i ] = ((uint16_t * )input )[i ];
107
103
}
108
- } else if (dma -> sample_resolution > 8 && dma -> output_resolution > 8 ) {
109
- size_t shift = 16 - dma -> output_resolution ;
110
- for (uint32_t i = 0 ; i < input_length / 2 ; i += dma -> sample_spacing ) {
111
- if (dma -> signed_to_unsigned ) {
112
- ((uint16_t * )* output )[out_i ] = ((int16_t * )input )[i ] + 0x8000 ;
113
- } else if (dma -> unsigned_to_signed ) {
114
- ((int16_t * )* output )[out_i ] = ((uint16_t * )input )[i ] - 0x8000 ;
104
+ if (dma -> output_resolution < 16 ) {
105
+ if (dma -> output_signed ) {
106
+ ((int16_t * )output )[out_i ] = ((int16_t * )output )[out_i ] >> shift ;
115
107
} else {
116
- ((uint16_t * )* output )[out_i ] = ((uint16_t * )input )[i ];
117
- }
118
- if (dma -> output_resolution < 16 ) {
119
- if (dma -> output_signed ) {
120
- ((int16_t * )* output )[out_i ] = ((int16_t * )* output )[out_i ] >> shift ;
121
- } else {
122
- ((uint16_t * )* output )[out_i ] = ((uint16_t * )* output )[out_i ] >> shift ;
123
- }
108
+ ((uint16_t * )output )[out_i ] = ((uint16_t * )output )[out_i ] >> shift ;
124
109
}
125
- out_i += 1 ;
126
110
}
127
- } else {
128
- // (dma->sample_resolution > 8 && dma->output_resolution <= 8)
129
- // Not currently used, but might be in the future.
130
- mp_raise_RuntimeError (translate ("Audio conversion not implemented" ));
111
+ out_i += 1 ;
131
112
}
132
113
} else {
133
- // No conversion necessary. Designate the input buffer as the output buffer.
134
- * output = input ;
135
- * output_length = input_length ;
114
+ // (dma->sample_resolution > 8 && dma->output_resolution <= 8)
115
+ // Not currently used, but might be in the future.
116
+ mp_raise_RuntimeError ( translate ( "Audio conversion not implemented" )) ;
136
117
}
137
118
#pragma GCC diagnostic pop
119
+ return output_length_used ;
138
120
}
139
121
140
122
// buffer_idx is 0 or 1.
@@ -154,21 +136,14 @@ STATIC void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) {
154
136
155
137
// Convert the sample format resolution and signedness, as necessary.
156
138
// The input sample buffer is what was read from a file, Mixer, or a raw sample buffer.
157
- // The output buffer is one of the DMA buffers (passed in), or if no conversion was done,
158
- // the original sample buffer (to save copying).
159
-
160
- // audio_dma_convert_samples() will write the converted samples into the given output
161
- // buffer if necessary. If no conversion was needed, it will return the sample buffer
162
- // as the output buffer.
163
- uint8_t * output_buffer ;
164
- uint32_t output_buffer_length ;
139
+ // The output buffer is one of the DMA buffers (passed in).
165
140
166
- audio_dma_convert_samples ( dma , sample_buffer , sample_buffer_length ,
167
- dma -> buffer [ buffer_idx ], dma -> buffer_length [ buffer_idx ] ,
168
- & output_buffer , & output_buffer_length );
141
+ size_t output_length_used = audio_dma_convert_samples (
142
+ dma , sample_buffer , sample_buffer_length ,
143
+ dma -> buffer [ buffer_idx ], dma -> buffer_length [ buffer_idx ] );
169
144
170
- dma_channel_set_read_addr (dma_channel , output_buffer , false /* trigger */ );
171
- dma_channel_set_trans_count (dma_channel , output_buffer_length / dma -> output_size , false /* trigger */ );
145
+ dma_channel_set_read_addr (dma_channel , dma -> buffer [ buffer_idx ] , false /* trigger */ );
146
+ dma_channel_set_trans_count (dma_channel , output_length_used / dma -> output_size , false /* trigger */ );
172
147
173
148
if (get_buffer_result == GET_BUFFER_DONE ) {
174
149
if (dma -> loop ) {
@@ -180,7 +155,7 @@ STATIC void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) {
180
155
(c -> al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS ) |
181
156
(dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB );
182
157
183
- if (output_buffer_length == 0 &&
158
+ if (output_length_used == 0 &&
184
159
!dma_channel_is_busy (dma -> channel [0 ]) &&
185
160
!dma_channel_is_busy (dma -> channel [1 ])) {
186
161
// No data has been read, and both DMA channels have now finished, so it's safe to stop.
0 commit comments