Changeset bb67def in mainline
- Timestamp:
- 2012-07-16T21:06:11Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 389ef25
- Parents:
- 50fa3f7
- Location:
- uspace/srv/audio/hound
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/audio/hound/audio_format.c
r50fa3f7 rbb67def 38 38 #include <errno.h> 39 39 #include <macros.h> 40 #include <stdio.h> 40 41 41 42 #include "audio_format.h" … … 63 64 #define int32_t_be2host(x) uint32_t_be2host(x) 64 65 #define host2int32_t_be(x) host2uint32_t_be(x) 66 67 // TODO float endian? 68 #define float_le2host(x) (x) 69 #define float_be2host(x) (x) 70 71 #define host2float_le(x) (x) 72 #define host2float_be(x) (x) 73 74 #define from(x, type, endian) (float)(type ## _ ## endian ## 2host(x)) 75 #define to(x, type, endian) (float)(host2 ## type ## _ ## endian(x)) 76 77 static float get_normalized_sample(const void *buffer, size_t size, 78 unsigned frame, unsigned channel, const audio_format_t *f); 65 79 66 80 bool audio_format_same(const audio_format_t *a, const audio_format_t* b) … … 84 98 /* This is so ugly it eats kittens, and puppies, and ducklings, 85 99 * and all little fluffy things... 86 * AND it does not check for overflows (FIXME)*/87 #define LOOP_ADD(type, endian, max) \100 */ 101 #define LOOP_ADD(type, endian, low, high) \ 88 102 do { \ 89 const type *src_buff = src; \ 90 type *dst_buff = dst; \ 91 for (size_t i = 0; i < size / sizeof(type); ++i) { \ 92 const float a = type ## _ ## endian ##2host(dst_buff[i]); \ 93 const float b = type ## _ ## endian ##2host(src_buff[i]); \ 94 float c = min((a + b), max); \ 95 if (c <= (float)-max) c = -max + 1.0; \ 96 dst_buff[i] = host2 ## type ## _ ## endian(c); \ 103 const unsigned frame_size = audio_format_frame_size(f); \ 104 const unsigned frame_count = size / frame_size; \ 105 for (size_t i = 0; i < frame_count; ++i) { \ 106 for (unsigned j = 0; j < f->channels; ++j) { \ 107 const float a = \ 108 get_normalized_sample(dst, size, i, j, f);\ 109 const float b = \ 110 get_normalized_sample(src, size, i, j, f);\ 111 float c = (a + b); \ 112 if (c < -1.0) c = -1.0; \ 113 if (c > 1.0) c = 1.0; \ 114 c += 1.0; \ 115 c *= ((float)(type)high - (float)(type)low) / 2; \ 116 c += (float)(type)low; \ 117 if (c > (float)(type)high) { \ 118 printf("SCALE HIGH failed\n"); \ 119 } \ 120 if (c < (float)(type)low) { \ 121 printf("SCALE LOW failed\n"); \ 122 } \ 123 type *dst_buf = dst; \ 124 const unsigned pos = i * f->channels + j; \ 125 if (pos < (size / sizeof(type))) \ 126 dst_buf[pos] = to((type)c, type, endian); \ 127 } \ 97 128 } \ 98 129 } while (0) 99 130 100 131 switch (f->sample_format) { 101 case PCM_SAMPLE_UINT8: { 102 const uint8_t *src_buff = src; 103 uint8_t *dst_buff = dst; 104 for (size_t i = 0; i < size; ++i ) 105 dst_buff[i] += src_buff[i]; 106 break; 107 } 108 case PCM_SAMPLE_SINT8: { 109 const int8_t *src_buff = src; 110 int8_t *dst_buff = dst; 111 for (size_t i = 0; i < size; ++i) 112 dst_buff[i] += src_buff[i]; 113 break; 114 } 132 case PCM_SAMPLE_UINT8: 133 LOOP_ADD(uint8_t, le, UINT8_MIN, UINT8_MAX); break; 134 case PCM_SAMPLE_SINT8: 135 LOOP_ADD(uint8_t, le, INT8_MIN, INT8_MAX); break; 115 136 case PCM_SAMPLE_UINT16_LE: 116 LOOP_ADD(uint16_t, le, UINT16_M AX); break;137 LOOP_ADD(uint16_t, le, UINT16_MIN, UINT16_MAX); break; 117 138 case PCM_SAMPLE_SINT16_LE: 118 LOOP_ADD(int16_t, le, INT16_M AX); break;139 LOOP_ADD(int16_t, le, INT16_MIN, INT16_MAX); break; 119 140 case PCM_SAMPLE_UINT16_BE: 120 LOOP_ADD(uint16_t, be, UINT16_M AX); break;141 LOOP_ADD(uint16_t, be, UINT16_MIN, UINT16_MAX); break; 121 142 case PCM_SAMPLE_SINT16_BE: 122 LOOP_ADD(int16_t, be, INT16_M AX); break;143 LOOP_ADD(int16_t, be, INT16_MIN, INT16_MAX); break; 123 144 case PCM_SAMPLE_UINT24_32_LE: 124 case PCM_SAMPLE_UINT32_LE: 125 LOOP_ADD(uint32_t, le, UINT32_M AX); break;145 case PCM_SAMPLE_UINT32_LE: // TODO this are not right for 24bit 146 LOOP_ADD(uint32_t, le, UINT32_MIN, UINT32_MAX); break; 126 147 case PCM_SAMPLE_SINT24_32_LE: 127 148 case PCM_SAMPLE_SINT32_LE: 128 LOOP_ADD(int32_t, le, INT32_M AX); break;149 LOOP_ADD(int32_t, le, INT32_MIN, INT32_MAX); break; 129 150 case PCM_SAMPLE_UINT24_32_BE: 130 151 case PCM_SAMPLE_UINT32_BE: 131 LOOP_ADD(uint32_t, be, UINT32_M AX); break;152 LOOP_ADD(uint32_t, be, UINT32_MIN, UINT32_MAX); break; 132 153 case PCM_SAMPLE_SINT24_32_BE: 133 154 case PCM_SAMPLE_SINT32_BE: 134 LOOP_ADD(int32_t, be, INT32_M AX); break;155 LOOP_ADD(int32_t, be, INT32_MIN, INT32_MAX); break; 135 156 case PCM_SAMPLE_UINT24_LE: 136 157 case PCM_SAMPLE_SINT24_LE: … … 142 163 } 143 164 return EOK; 165 #undef LOOP_ADD 144 166 } 145 167 168 /** Converts all sample formats to float <-1,1> */ 169 static float get_normalized_sample(const void *buffer, size_t size, 170 unsigned frame, unsigned channel, const audio_format_t *f) 171 { 172 assert(f); 173 if (channel >= f->channels) 174 return 0.0f; 175 #define GET(type, endian, low, high) \ 176 do { \ 177 const type *src = buffer; \ 178 const size_t sample_count = size / sizeof(type); \ 179 const size_t sample_pos = frame * f->channels + channel; \ 180 if (sample_pos >= sample_count) {\ 181 return 0.0f; \ 182 } \ 183 float sample = from(src[sample_pos], type, endian); \ 184 /* This makes it positive */ \ 185 sample -= (float)(type)low; \ 186 if (sample < 0.0f) { \ 187 printf("SUB MIN failed\n"); \ 188 } \ 189 /* This makes it <0,2> */ \ 190 sample /= (((float)(type)high - (float)(type)low) / 2.0f); \ 191 if (sample > 2.0) { \ 192 printf("DIV RANGE failed\n"); \ 193 } \ 194 return sample - 1.0f; \ 195 } while (0) 196 197 switch (f->sample_format) { 198 case PCM_SAMPLE_UINT8: 199 GET(uint8_t, le, UINT8_MIN, UINT8_MAX); 200 case PCM_SAMPLE_SINT8: 201 GET(int8_t, le, INT8_MIN, INT8_MAX); 202 case PCM_SAMPLE_UINT16_LE: 203 GET(uint16_t, le, UINT16_MIN, UINT16_MAX); 204 case PCM_SAMPLE_SINT16_LE: 205 GET(int16_t, le, INT16_MIN, INT16_MAX); 206 case PCM_SAMPLE_UINT16_BE: 207 GET(uint16_t, be, UINT16_MIN, UINT16_MAX); 208 case PCM_SAMPLE_SINT16_BE: 209 GET(int16_t, be, INT16_MIN, INT16_MAX); 210 case PCM_SAMPLE_UINT24_32_LE: 211 case PCM_SAMPLE_UINT32_LE: 212 GET(uint32_t, le, UINT32_MIN, UINT32_MAX); 213 case PCM_SAMPLE_SINT24_32_LE: 214 case PCM_SAMPLE_SINT32_LE: 215 GET(int32_t, le, INT32_MIN, INT32_MAX); 216 case PCM_SAMPLE_UINT24_32_BE: 217 case PCM_SAMPLE_UINT32_BE: 218 GET(uint32_t, be, UINT32_MIN, UINT32_MAX); 219 case PCM_SAMPLE_SINT24_32_BE: 220 case PCM_SAMPLE_SINT32_BE: 221 GET(int32_t, le, INT32_MIN, INT32_MAX); 222 case PCM_SAMPLE_UINT24_LE: 223 case PCM_SAMPLE_SINT24_LE: 224 case PCM_SAMPLE_UINT24_BE: 225 case PCM_SAMPLE_SINT24_BE: 226 case PCM_SAMPLE_FLOAT32: 227 default: ; 228 } 229 return 0; 230 #undef GET 231 } 146 232 /** 147 233 * @} -
uspace/srv/audio/hound/audio_source.c
r50fa3f7 rbb67def 116 116 return EINVAL; 117 117 } 118 if ( !audio_format_same(&source->format, f)) {119 log_debug(" Format conversion is not supportedyet");118 if (source->format.sampling_rate != f->sampling_rate) { 119 log_debug("Resampling is not supported, yet"); 120 120 return ENOTSUP; 121 121 }
Note:
See TracChangeset
for help on using the changeset viewer.