|
1 | 1 | /* Extended Module Player |
2 | | - * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr |
| 2 | + * Copyright (C) 1996-2026 Claudio Matsuoka and Hipolito Carraro Jr |
3 | 3 | * |
4 | 4 | * This file is part of the Extended Module Player and is distributed |
5 | 5 | * under the terms of the GNU General Public License. See the COPYING |
@@ -101,16 +101,105 @@ const struct sound_driver *select_sound_driver(struct options *options) |
101 | 101 | return NULL; |
102 | 102 | } |
103 | 103 |
|
104 | | -/* Convert little-endian 16 bit samples to big-endian */ |
105 | | -void convert_endian(unsigned char *p, int l) |
| 104 | +/* Downmix 32-bit to 24-bit aligned (in-place) */ |
| 105 | +void downmix_32_to_24_aligned(unsigned char *buffer, int buffer_bytes) |
| 106 | +{ |
| 107 | + /* Note: most 24-bit support ignores the high byte. |
| 108 | + * sndio, however, expects 24-bit to be sign extended. */ |
| 109 | + int *buf32 = (int *)buffer; |
| 110 | + int i; |
| 111 | + |
| 112 | + for (i = 0; i < buffer_bytes; i += 4) { |
| 113 | + *buf32 >>= 8; |
| 114 | + buf32++; |
| 115 | + } |
| 116 | +} |
| 117 | + |
| 118 | +/* Downmix 32-bit to 24-bit packed (in-place). |
| 119 | + * Returns the new number of useful bytes in the buffer. */ |
| 120 | +int downmix_32_to_24_packed(unsigned char *buffer, int buffer_bytes) |
| 121 | +{ |
| 122 | + unsigned char *out = buffer; |
| 123 | + int buffer_samples = buffer_bytes >> 2; |
| 124 | + int i; |
| 125 | + |
| 126 | + /* Big endian 32-bit (22 11 00 XX) -> 24-bit (22 11 00) |
| 127 | + * Little endian 32-bit (XX 00 11 22) -> 24-bit (00 11 22) |
| 128 | + * Skip the first byte for little endian to allow reusing the same loop. |
| 129 | + */ |
| 130 | + if (!is_big_endian()) { |
| 131 | + buffer++; |
| 132 | + } |
| 133 | + |
| 134 | + for (i = 0; i < buffer_samples; i++) { |
| 135 | + out[0] = buffer[0]; |
| 136 | + out[1] = buffer[1]; |
| 137 | + out[2] = buffer[2]; |
| 138 | + out += 3; |
| 139 | + buffer += 4; |
| 140 | + } |
| 141 | + |
| 142 | + return buffer_samples * 3; |
| 143 | +} |
| 144 | + |
| 145 | + |
| 146 | +/* Convert native endian 16-bit samples for file IO */ |
| 147 | +void convert_endian_16bit(unsigned char *buffer, int buffer_bytes) |
106 | 148 | { |
107 | 149 | unsigned char b; |
108 | 150 | int i; |
109 | 151 |
|
110 | | - for (i = 0; i < l; i++) { |
111 | | - b = p[0]; |
112 | | - p[0] = p[1]; |
113 | | - p[1] = b; |
114 | | - p += 2; |
| 152 | + for (i = 0; i < buffer_bytes; i += 2) { |
| 153 | + b = buffer[0]; |
| 154 | + buffer[0] = buffer[1]; |
| 155 | + buffer[1] = b; |
| 156 | + buffer += 2; |
| 157 | + } |
| 158 | +} |
| 159 | + |
| 160 | +/* Convert native endian 24-bit unaligned samples for file IO */ |
| 161 | +void convert_endian_24bit(unsigned char *buffer, int buffer_bytes) |
| 162 | +{ |
| 163 | + unsigned char b; |
| 164 | + int i; |
| 165 | + |
| 166 | + for (i = 0; i < buffer_bytes; i += 3) { |
| 167 | + b = buffer[0]; |
| 168 | + buffer[0] = buffer[2]; |
| 169 | + buffer[2] = b; |
| 170 | + buffer += 3; |
| 171 | + } |
| 172 | +} |
| 173 | + |
| 174 | +/* Convert native endian 32-bit samples for file IO */ |
| 175 | +void convert_endian_32bit(unsigned char *buffer, int buffer_bytes) |
| 176 | +{ |
| 177 | + unsigned char a, b; |
| 178 | + int i; |
| 179 | + |
| 180 | + for (i = 0; i < buffer_bytes; i += 4) { |
| 181 | + a = buffer[0]; |
| 182 | + b = buffer[1]; |
| 183 | + buffer[0] = buffer[3]; |
| 184 | + buffer[1] = buffer[2]; |
| 185 | + buffer[2] = b; |
| 186 | + buffer[3] = a; |
| 187 | + buffer += 4; |
| 188 | + } |
| 189 | +} |
| 190 | + |
| 191 | +/* Convert native endian 16-bit, 24-bit, or 32-bit samples for file IO */ |
| 192 | +void convert_endian(unsigned char *buffer, int buffer_bytes, int bits) |
| 193 | +{ |
| 194 | + switch (bits) { |
| 195 | + case 16: |
| 196 | + convert_endian_16bit(buffer, buffer_bytes); |
| 197 | + break; |
| 198 | + case 24: |
| 199 | + convert_endian_24bit(buffer, buffer_bytes); |
| 200 | + break; |
| 201 | + case 32: |
| 202 | + convert_endian_32bit(buffer, buffer_bytes); |
| 203 | + break; |
115 | 204 | } |
116 | 205 | } |
0 commit comments