1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. 3 * Copyright (c) 2002-2007, Jerome Duval (jerome.duval@free.fr) 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include "MultiAudioUtility.h" 10 11 #include <errno.h> 12 13 #include <MediaDefs.h> 14 15 16 const float kSampleRates[] = { 17 8000.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, 44100.0, 18 48000.0, 64000.0, 88200.0, 96000.0, 176400.0, 192000.0, 384000.0, 1536000.0 19 }; 20 const uint32 kSampleRateCount = sizeof(kSampleRates) / sizeof(kSampleRates[0]); 21 22 23 template<typename T> static status_t 24 call_driver(int device, int32 op, T* data) 25 { 26 if (ioctl(device, op, data, sizeof(T)) != 0) 27 return errno; 28 29 return B_OK; 30 } 31 32 33 namespace MultiAudio { 34 35 36 float 37 convert_to_sample_rate(uint32 rate) 38 { 39 for (uint32 i = 0; i < kSampleRateCount; i++) { 40 if (rate & 1) 41 return kSampleRates[i]; 42 43 rate >>= 1; 44 } 45 46 return 0.0; 47 } 48 49 50 uint32 51 convert_from_sample_rate(float rate) 52 { 53 for (uint32 i = 0; i < kSampleRateCount; i++) { 54 if (rate <= kSampleRates[i]) 55 return 1 << i; 56 } 57 58 return 0; 59 } 60 61 62 uint32 63 convert_to_media_format(uint32 format) 64 { 65 switch (format) { 66 case B_FMT_FLOAT: 67 return media_raw_audio_format::B_AUDIO_FLOAT; 68 case B_FMT_18BIT: 69 case B_FMT_20BIT: 70 case B_FMT_24BIT: 71 case B_FMT_32BIT: 72 return media_raw_audio_format::B_AUDIO_INT; 73 case B_FMT_16BIT: 74 return media_raw_audio_format::B_AUDIO_SHORT; 75 case B_FMT_8BIT_S: 76 return media_raw_audio_format::B_AUDIO_CHAR; 77 case B_FMT_8BIT_U: 78 return media_raw_audio_format::B_AUDIO_UCHAR; 79 80 default: 81 return 0; 82 } 83 } 84 85 86 int16 87 convert_to_valid_bits(uint32 format) 88 { 89 switch (format) { 90 case B_FMT_18BIT: 91 return 18; 92 case B_FMT_20BIT: 93 return 20; 94 case B_FMT_24BIT: 95 return 24; 96 case B_FMT_32BIT: 97 return 32; 98 99 default: 100 return 0; 101 } 102 } 103 104 105 uint32 106 convert_from_media_format(uint32 format) 107 { 108 switch (format) { 109 case media_raw_audio_format::B_AUDIO_FLOAT: 110 return B_FMT_FLOAT; 111 case media_raw_audio_format::B_AUDIO_INT: 112 return B_FMT_32BIT; 113 case media_raw_audio_format::B_AUDIO_SHORT: 114 return B_FMT_16BIT; 115 case media_raw_audio_format::B_AUDIO_CHAR: 116 return B_FMT_8BIT_S; 117 case media_raw_audio_format::B_AUDIO_UCHAR: 118 return B_FMT_8BIT_U; 119 120 default: 121 return 0; 122 } 123 } 124 125 126 uint32 127 select_sample_rate(uint32 rate) 128 { 129 // highest rate 130 uint32 crate = B_SR_1536000; 131 while (crate != 0) { 132 if (rate & crate) 133 return crate; 134 crate >>= 1; 135 } 136 return 0; 137 } 138 139 140 uint32 141 select_format(uint32 format) 142 { 143 // best format 144 // TODO ensure we support this format 145 /*if (format & B_FMT_FLOAT) 146 return B_FMT_FLOAT;*/ 147 if (format & B_FMT_32BIT) 148 return B_FMT_32BIT; 149 if (format & B_FMT_24BIT) 150 return B_FMT_24BIT; 151 if (format & B_FMT_20BIT) 152 return B_FMT_20BIT; 153 if (format & B_FMT_18BIT) 154 return B_FMT_18BIT; 155 if (format & B_FMT_16BIT) 156 return B_FMT_16BIT; 157 if (format & B_FMT_8BIT_S) 158 return B_FMT_8BIT_S; 159 if (format & B_FMT_8BIT_U) 160 return B_FMT_8BIT_U; 161 162 return 0; 163 } 164 165 166 status_t 167 get_description(int device, multi_description* description) 168 { 169 return call_driver(device, B_MULTI_GET_DESCRIPTION, description); 170 } 171 172 173 status_t 174 get_enabled_channels(int device, multi_channel_enable* enable) 175 { 176 return call_driver(device, B_MULTI_GET_ENABLED_CHANNELS, enable); 177 } 178 179 180 status_t 181 set_enabled_channels(int device, multi_channel_enable* enable) 182 { 183 return call_driver(device, B_MULTI_SET_ENABLED_CHANNELS, enable); 184 } 185 186 187 status_t 188 get_global_format(int device, multi_format_info* info) 189 { 190 return call_driver(device, B_MULTI_GET_GLOBAL_FORMAT, info); 191 } 192 193 194 status_t 195 set_global_format(int device, multi_format_info* info) 196 { 197 return call_driver(device, B_MULTI_SET_GLOBAL_FORMAT, info); 198 } 199 200 201 status_t 202 get_buffers(int device, multi_buffer_list* list) 203 { 204 return call_driver(device, B_MULTI_GET_BUFFERS, list); 205 } 206 207 208 status_t 209 buffer_exchange(int device, multi_buffer_info* info) 210 { 211 return call_driver(device, B_MULTI_BUFFER_EXCHANGE, info); 212 } 213 214 215 status_t 216 list_mix_controls(int device, multi_mix_control_info* info) 217 { 218 return call_driver(device, B_MULTI_LIST_MIX_CONTROLS, info); 219 } 220 221 222 status_t 223 get_mix(int device, multi_mix_value_info* info) 224 { 225 return call_driver(device, B_MULTI_GET_MIX, info); 226 } 227 228 229 status_t 230 set_mix(int device, multi_mix_value_info* info) 231 { 232 return call_driver(device, B_MULTI_SET_MIX, info); 233 } 234 235 236 } // namespace MultiAudio 237