[17] | 1 | /* -*- mode: C; tab-width:8; c-basic-offset:8 -*- |
---|
| 2 | * vi:set ts=8: |
---|
| 3 | * |
---|
| 4 | * ac_channels.c |
---|
| 5 | * |
---|
| 6 | * audioconvert function related to number of audio channels |
---|
| 7 | */ |
---|
| 8 | |
---|
| 9 | #include "al_siteconfig.h" |
---|
| 10 | |
---|
| 11 | #include <AL/al.h> |
---|
| 12 | #include <stdio.h> |
---|
| 13 | |
---|
| 14 | #include "audioconvert/audioconvert.h" |
---|
| 15 | |
---|
| 16 | /* Duplicate a mono channel to both stereo channels */ |
---|
| 17 | void acConvertStereo(acAudioCVT *cvt, ALushort format) { |
---|
| 18 | int i; |
---|
| 19 | |
---|
| 20 | if((format & 0xFF) == 16) { |
---|
| 21 | ALushort *src, *dst; |
---|
| 22 | |
---|
| 23 | src = (ALushort *) cvt->buf; |
---|
| 24 | dst = (ALushort *) cvt->buf; |
---|
| 25 | src += cvt->len_cvt / sizeof *src; |
---|
| 26 | dst += cvt->len_cvt * 2 / sizeof *dst; |
---|
| 27 | |
---|
| 28 | for ( i=cvt->len_cvt/2; i; --i ) { |
---|
| 29 | dst -= 2; |
---|
| 30 | src -= 1; |
---|
| 31 | dst[0] = src[0]; |
---|
| 32 | dst[1] = src[0]; |
---|
| 33 | } |
---|
| 34 | } else { |
---|
| 35 | ALubyte *src, *dst; |
---|
| 36 | |
---|
| 37 | src = (ALubyte *) cvt->buf + cvt->len_cvt; |
---|
| 38 | dst = (ALubyte *) cvt->buf + cvt->len_cvt * 2; |
---|
| 39 | for(i = cvt->len_cvt; i; i-- ) { |
---|
| 40 | dst -= 2; |
---|
| 41 | src -= 1; |
---|
| 42 | dst[0] = src[0]; |
---|
| 43 | dst[1] = src[0]; |
---|
| 44 | } |
---|
| 45 | } |
---|
| 46 | |
---|
| 47 | cvt->len_cvt *= 2; |
---|
| 48 | |
---|
| 49 | if ( cvt->filters[++cvt->filter_index] ) { |
---|
| 50 | cvt->filters[cvt->filter_index](cvt, format); |
---|
| 51 | } |
---|
| 52 | } |
---|
| 53 | |
---|
| 54 | /* Effectively mix right and left channels into a single channel */ |
---|
| 55 | void acConvertMono(acAudioCVT *cvt, ALushort format) { |
---|
| 56 | int i; |
---|
| 57 | ALint sample; |
---|
| 58 | |
---|
| 59 | switch(format & 0x8018) { |
---|
| 60 | case AUDIO_U8: { |
---|
| 61 | ALubyte *src, *dst; |
---|
| 62 | |
---|
| 63 | src = cvt->buf; |
---|
| 64 | dst = cvt->buf; |
---|
| 65 | for ( i=cvt->len_cvt/2; i; --i ) { |
---|
| 66 | sample = src[0] + src[1]; |
---|
| 67 | sample /= 2; |
---|
| 68 | |
---|
| 69 | if ( sample > 255 ) { |
---|
| 70 | *dst = 255; |
---|
| 71 | } else { |
---|
| 72 | *dst = sample; |
---|
| 73 | } |
---|
| 74 | src += 2; |
---|
| 75 | dst += 1; |
---|
| 76 | } |
---|
| 77 | } |
---|
| 78 | break; |
---|
| 79 | |
---|
| 80 | case AUDIO_S8: { |
---|
| 81 | ALbyte *src, *dst; |
---|
| 82 | |
---|
| 83 | src = (ALbyte *)cvt->buf; |
---|
| 84 | dst = (ALbyte *)cvt->buf; |
---|
| 85 | for ( i=cvt->len_cvt/2; i; --i ) { |
---|
| 86 | sample = src[0] + src[1]; |
---|
| 87 | sample /= 2; |
---|
| 88 | |
---|
| 89 | if ( sample > 127 ) { |
---|
| 90 | *dst = 127; |
---|
| 91 | } else |
---|
| 92 | if ( sample < -128 ) { |
---|
| 93 | *dst = -128; |
---|
| 94 | } else { |
---|
| 95 | *dst = sample; |
---|
| 96 | } |
---|
| 97 | src += 2; |
---|
| 98 | dst += 1; |
---|
| 99 | } |
---|
| 100 | } |
---|
| 101 | break; |
---|
| 102 | |
---|
| 103 | case AUDIO_U16LSB: { |
---|
| 104 | ALubyte *src, *dst; |
---|
| 105 | |
---|
| 106 | src = cvt->buf; |
---|
| 107 | dst = cvt->buf; |
---|
| 108 | if ( (format & 0x1000) == 0x1000 ) { |
---|
| 109 | for ( i=cvt->len_cvt/4; i; --i ) { |
---|
| 110 | sample = (ALushort)((src[0]<<8)|src[1])+ |
---|
| 111 | (ALushort)((src[2]<<8)|src[3]); |
---|
| 112 | sample /= 2; |
---|
| 113 | |
---|
| 114 | if ( sample > 65535 ) { |
---|
| 115 | dst[0] = 0xFF; |
---|
| 116 | dst[1] = 0xFF; |
---|
| 117 | } else { |
---|
| 118 | dst[1] = (sample&0xFF); |
---|
| 119 | sample >>= 8; |
---|
| 120 | dst[0] = (sample&0xFF); |
---|
| 121 | } |
---|
| 122 | src += 4; |
---|
| 123 | dst += 2; |
---|
| 124 | } |
---|
| 125 | } else { |
---|
| 126 | for ( i=cvt->len_cvt/4; i; --i ) { |
---|
| 127 | sample = (ALushort)((src[1]<<8)|src[0])+ |
---|
| 128 | (ALushort)((src[3]<<8)|src[2]); |
---|
| 129 | sample /= 2; |
---|
| 130 | |
---|
| 131 | if ( sample > 65535 ) { |
---|
| 132 | dst[0] = 0xFF; |
---|
| 133 | dst[1] = 0xFF; |
---|
| 134 | } else { |
---|
| 135 | dst[0] = (sample&0xFF); |
---|
| 136 | sample >>= 8; |
---|
| 137 | dst[1] = (sample&0xFF); |
---|
| 138 | } |
---|
| 139 | src += 4; |
---|
| 140 | dst += 2; |
---|
| 141 | } |
---|
| 142 | } |
---|
| 143 | } |
---|
| 144 | break; |
---|
| 145 | |
---|
| 146 | case AUDIO_S16LSB: { |
---|
| 147 | ALubyte *src, *dst; |
---|
| 148 | |
---|
| 149 | src = cvt->buf; |
---|
| 150 | dst = cvt->buf; |
---|
| 151 | if ( (format & 0x1000) == 0x1000 ) { |
---|
| 152 | for ( i=cvt->len_cvt/4; i; --i ) { |
---|
| 153 | sample = (ALshort)((src[0]<<8)|src[1])+ |
---|
| 154 | (ALshort)((src[2]<<8)|src[3]); |
---|
| 155 | sample /= 2; |
---|
| 156 | |
---|
| 157 | if ( sample > 32767 ) { |
---|
| 158 | dst[0] = 0x7F; |
---|
| 159 | dst[1] = 0xFF; |
---|
| 160 | } else |
---|
| 161 | if ( sample < -32768 ) { |
---|
| 162 | dst[0] = 0x80; |
---|
| 163 | dst[1] = 0x00; |
---|
| 164 | } else { |
---|
| 165 | dst[1] = (sample&0xFF); |
---|
| 166 | sample >>= 8; |
---|
| 167 | dst[0] = (sample&0xFF); |
---|
| 168 | } |
---|
| 169 | src += 4; |
---|
| 170 | dst += 2; |
---|
| 171 | } |
---|
| 172 | } else { |
---|
| 173 | for ( i=cvt->len_cvt/4; i; --i ) { |
---|
| 174 | sample = (ALshort)((src[1]<<8)|src[0])+ |
---|
| 175 | (ALshort)((src[3]<<8)|src[2]); |
---|
| 176 | sample /= 2; |
---|
| 177 | |
---|
| 178 | if ( sample > 32767 ) { |
---|
| 179 | dst[1] = 0x7F; |
---|
| 180 | dst[0] = 0xFF; |
---|
| 181 | } else |
---|
| 182 | if ( sample < -32768 ) { |
---|
| 183 | dst[1] = 0x80; |
---|
| 184 | dst[0] = 0x00; |
---|
| 185 | } else { |
---|
| 186 | dst[0] = (sample&0xFF); |
---|
| 187 | sample >>= 8; |
---|
| 188 | dst[1] = (sample&0xFF); |
---|
| 189 | } |
---|
| 190 | src += 4; |
---|
| 191 | dst += 2; |
---|
| 192 | } |
---|
| 193 | } |
---|
| 194 | } |
---|
| 195 | break; |
---|
| 196 | } |
---|
| 197 | cvt->len_cvt /= 2; |
---|
| 198 | |
---|
| 199 | if ( cvt->filters[++cvt->filter_index] ) { |
---|
| 200 | cvt->filters[cvt->filter_index](cvt, format); |
---|
| 201 | } |
---|
| 202 | } |
---|