1 /* 2 * Copyright (C) 2002 - David W. Durham 3 * 4 * This file is part of ReZound, an audio editing application. 5 * 6 * ReZound is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published 8 * by the Free Software Foundation; either version 2 of the License, 9 * or (at your option) any later version. 10 * 11 * ReZound is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 */ 20 21 #ifndef __CSound_defs_H__ 22 #define __CSound_defs_H__ 23 24 #include "../../config/common.h" 25 26 class CSound; 27 28 #include <stdint.h> 29 30 // ??? rename to something more specific to audio, PCM, or rezound 31 // create a MAX_LENGTH that I check for in the methods... I've made it, but I don't think I use it yet much 32 // right now I made this lower only because I haven't made the frontend dialogs not show unnecessary check boxes and such...so the dialogs were huge even when many channels were not in use 33 // if this is changed, also consider the array size of gJACKOutputPortNames and gJACKInputPortNames in settings.h/cpp (although it should be big enough) 34 #define MAX_CHANNELS 8 35 36 37 38 /* 39 * audio size specifications 40 * 41 * sample_pos_t should always be unsigned since I use this assumption and never check for < 0 in the code 42 * sample_fpos_t should be floating point, but big enough to hold all values of sample_pos_t 43 */ 44 #ifdef ENABLE_LARGEFILE 45 46 // 64 bit 47 typedef int64_t sample_pos_t; // integer sample position 48 typedef long double sample_fpos_t; // floating-point sample position 49 50 #define MAX_LENGTH (0x7fffffffffffffffLL-(1024LL*1024LL)) 51 52 #include <math.h> 53 extern "C" { 54 long double logl(long double); 55 long double expl(long double); 56 } 57 #define sample_fpos_floor(a) (floorl(a)) 58 #define sample_fpos_ceil(a) (ceill(a)) 59 #define sample_fpos_round(a) (nearbyintl(a)) 60 #define sample_fpos_log(a) (logl(a)) 61 #define sample_fpos_exp(a) (expl(a)) 62 #define sample_fpos_fabs(a) (fabsl(a)) 63 #define sample_fpos_sin(a) (sinl(a)) 64 #define sample_fpos_pow(a,b) (powl(a,b)) 65 66 #else 67 68 // 32 bit 69 typedef int32_t sample_pos_t; // integer sample count 70 typedef double sample_fpos_t; // floating-point sample count 71 72 #define MAX_LENGTH (0x7fffffff-(1024*1024)) 73 74 #include <math.h> 75 #define sample_fpos_floor(a) (floor(a)) 76 #define sample_fpos_ceil(a) (ceil(a)) 77 #define sample_fpos_round(a) (nearbyint(a)) 78 #define sample_fpos_log(a) (log(a)) 79 #define sample_fpos_exp(a) (exp(a)) 80 #define sample_fpos_fabs(a) (fabs(a)) 81 #define sample_fpos_sin(a) (sin(a)) 82 #define sample_fpos_pow(a,b) (pow(a,b)) 83 84 #endif 85 86 static const sample_pos_t NIL_SAMPLE_POS=~((sample_pos_t)0); 87 88 89 // audio type specifications 90 #if defined(SAMPLE_TYPE_S16) // 16 bit PCM 91 92 #define MAX_SAMPLE ((sample_t)32767) 93 #define MIN_SAMPLE ((sample_t)-MAX_SAMPLE) // these should stay symetric so I don't have to handle the possibility of them being off center in the frontend rendering 94 typedef int16_t sample_t; 95 typedef int_fast32_t mix_sample_t; // this needs to hold at least a value of MAX_SAMPLE squared 96 97 static mix_sample_t _SSS; 98 #define ClipSample(s) ((sample_t)(_SSS=((mix_sample_t)(s)), _SSS>MAX_SAMPLE ? MAX_SAMPLE : ( _SSS<MIN_SAMPLE ? MIN_SAMPLE : _SSS ) ) ) 99 100 #elif defined(SAMPLE_TYPE_FLOAT) // 32 bit floating point PCM 101 #define MAX_SAMPLE (1.0f) 102 #define MIN_SAMPLE (-MAX_SAMPLE) // these should stay symetric so I don't have to handle the possibility of them being off center in the frontend rendering 103 typedef float sample_t; 104 typedef float mix_sample_t; 105 106 // empty implementation so that samples are not truncated until playback 107 #define ClipSample(s) (s) 108 109 #else 110 #error no SAMPLE_TYPE_xxx defined -- was supposed to be defined from the configure script 111 #endif 112 113 114 115 /***************************/ 116 /* sample type conversions */ 117 /***************************/ 118 119 struct int24_t // int24_t -> unsigned char[3] 120 { 121 uint8_t data[3]; 122 123 enum { // indexes into data[] for the low, middle and high bytes 124 #ifdef WORDS_BIGENDIAN 125 lo=2, 126 mid=1, 127 hi=0 128 #else 129 lo=0, 130 mid=1, 131 hi=2 132 #endif 133 }; 134 setint24_t135 inline void set(const int_fast32_t v) 136 { 137 data[lo]=v&0xff; 138 data[mid]=(v>>8)&0xff; 139 data[hi]=(v>>16)&0xff; 140 } 141 getint24_t142 inline int32_t get() const 143 { 144 if(data[hi]&0x80) // sign extension 145 return (int_fast32_t)data[lo] | ((int_fast32_t)data[mid]<<8) | ((int_fast32_t)data[hi]<<16) | (0xff<<24); 146 else 147 return (int_fast32_t)data[lo] | ((int_fast32_t)data[mid]<<8) | ((int_fast32_t)data[hi]<<16); 148 } 149 } 150 #ifdef __GNUC__ 151 __attribute__ ((packed)) 152 #endif 153 ; 154 155 #include <math.h> 156 157 // It is necessary to call this template function with the template arguments because the 158 // compiler cannot infer the specialization to used since not all the template parameters 159 // types are used in the function's parameter list. 160 // 161 // ??? Some of the implementation may one day need conditional expressions to handle the 162 // possibility that the negative range is one sample value larger than the positive range 163 /* just going to have to get a linker error now with gcc>=3.4 */ 164 template<typename from_sample_t,typename to_sample_t> static inline const to_sample_t convert_sample(const register from_sample_t sample) ;//{ sample_type_conversion_for_this_combination_unimplemented; } 165 166 // int8_t -> ... 167 // int8_t -> int8_t 168 template<> STATIC_TPL inline const int8_t convert_sample<int8_t,int8_t>(const register int8_t sample) { return sample; } 169 170 // int8_t -> int16_t 171 template<> STATIC_TPL inline const int16_t convert_sample<int8_t,int16_t>(const register int8_t sample) { return sample*256; } 172 173 // int8_t -> int24_t 174 //template<> static inline const int24_t convert_sample<int8_t,int24_t>(const register int8_t sample) { } 175 176 // int8_t -> int32_t 177 //template<> static inline const int32_t convert_sample<int8_t,int32_t>(const register int8_t sample) { } 178 179 // int8_t -> float 180 template<> STATIC_TPL inline const float convert_sample<int8_t,float>(const register int8_t sample) { return ((float)sample)/127.0f; } 181 182 // int8_t -> double 183 //template<> static inline const double convert_sample<int8_t,double>(const register int8_t sample) { } 184 185 186 // int16_t -> ... 187 // int16_t -> int8_t 188 template<> STATIC_TPL inline const int8_t convert_sample<int16_t,int8_t>(const register int16_t sample) { return sample/256; } 189 190 // int16_t -> int16_t 191 template<> STATIC_TPL inline const int16_t convert_sample<int16_t,int16_t>(const register int16_t sample) { return sample; } 192 193 // int16_t -> int24_t 194 template<> STATIC_TPL inline const int24_t convert_sample<int16_t,int24_t>(const register int16_t sample) { int24_t r; r.set(sample*256); return r; } 195 196 // int16_t -> int32_t 197 template<> STATIC_TPL inline const int32_t convert_sample<int16_t,int32_t>(const register int16_t sample) { return sample*65536; } 198 199 // int16_t -> float 200 template<> STATIC_TPL inline const float convert_sample<int16_t,float>(const register int16_t sample) { return (float)sample/32767.0f; } 201 202 // int16_t -> double 203 template<> STATIC_TPL inline const double convert_sample<int16_t,double>(const register int16_t sample) { return (double)sample/32767.0; } 204 205 206 // int24_t -> ... 207 // int24_t -> int8_t 208 //template<> static inline const int8_t convert_sample<int24_t,int8_t>(const int24_t sample) { } 209 210 // int24_t -> int16_t 211 template<> STATIC_TPL inline const int16_t convert_sample<int24_t,int16_t>(const int24_t sample) { return sample.get()>>8; } 212 213 // int24_t -> int24_t 214 template<> STATIC_TPL inline const int24_t convert_sample<int24_t,int24_t>(const int24_t sample) { return sample; } 215 216 // int24_t -> int32_t 217 //template<> static inline const int32_t convert_sample<int24_t,int32_t>(const int24_t sample) { } 218 219 // int24_t -> float 220 template<> STATIC_TPL inline const float convert_sample<int24_t,float>(const int24_t sample) { return sample.get()/8388607.0f; } 221 222 // int24_t -> double 223 //template<> static inline const double convert_sample<int24_t,double>(const int24_t sample) { } 224 225 226 // int32_t -> ... 227 // int32_t -> int8_t 228 //template<> static inline const int8_t convert_sample<int32_t,int8_t>(const register int32_t sample) { } 229 230 // int32_t -> int16_t 231 template<> STATIC_TPL inline const int16_t convert_sample<int32_t,int16_t>(const register int32_t sample) { return sample/65536; } 232 233 // int32_t -> int24_t 234 //template<> static inline const int24_t convert_sample<int32_t,int24_t>(const register int32_t sample) { } 235 236 // int32_t -> int32_t 237 template<> STATIC_TPL inline const int32_t convert_sample<int32_t,int32_t>(const register int32_t sample) { return sample; } 238 239 // int32_t -> float 240 template<> STATIC_TPL inline const float convert_sample<int32_t,float>(const register int32_t sample) { return ((double)sample)/2147483647.0; } 241 242 // int32_t -> double 243 //template<> static inline const double convert_sample<int32_t,double >(const register int32_t sample) { } 244 245 246 // float -> ... 247 // float -> int8_t 248 template<> STATIC_TPL inline const int8_t convert_sample<float,int8_t>(const register float sample) { return (int8_t)floorf((sample>1.0f ? 1.0f : (sample<-1.0f ? -1.0f : sample))*127.0f); } 249 250 // float -> int16_t 251 template<> STATIC_TPL inline const int16_t convert_sample<float,int16_t>(const register float sample) { return (int16_t)floorf((sample>1.0f ? 1.0f : (sample<-1.0f ? -1.0f : sample))*32767.0f); } 252 253 // float -> int24_t 254 template<> STATIC_TPL inline const int24_t convert_sample<float,int24_t>(const register float sample) { int24_t r; r.set((int_fast32_t)floorf((sample>1.0f ? 1.0f : (sample<-1.0f ? -1.0f : sample))*8388607.0f)); return r; } 255 256 // float -> int32_t 257 template<> STATIC_TPL inline const int32_t convert_sample<float,int32_t>(const register float sample) { return (int32_t) floor((double)(sample>1.0f ? 1.0f : (sample<-1.0f ? -1.0f : sample)) * 2147483647.0); } 258 259 // float -> float 260 template<> STATIC_TPL inline const float convert_sample<float,float>(const register float sample) { return sample; } 261 262 // float -> double 263 template<> STATIC_TPL inline const double convert_sample<float,double>(const register float sample) { return (double)sample; } 264 265 266 // double -> ... 267 // double -> int8_t 268 //template<> static inline const int8_t convert_sample<double,int8_t>(const register double sample) { } 269 270 // double -> int16_t 271 template<> STATIC_TPL inline const int16_t convert_sample<double,int16_t>(const register double sample) { return (int16_t)floor((sample>1.0 ? 1.0 : (sample<-1.0 ? -1.0 : sample))*32767.0); } 272 273 // double -> int24_t 274 //template<> static inline const int24_t convert_sample<double,int24_t>(const register double sample) { } 275 276 // double -> int32_t 277 //template<> static inline const int32_t convert_sample<double,int32_t>(const register double sample) { } 278 279 // double -> float 280 template<> STATIC_TPL inline const float convert_sample<double,float>(const register double sample) { return (float)sample; } 281 282 // double -> double 283 template<> STATIC_TPL inline const double convert_sample<double,double>(const register double sample) { return sample; } 284 285 286 287 288 289 290 291 // used in CSound::mixSound() 292 enum MixMethods 293 { 294 mmOverwrite, 295 mmAdd, 296 mmSubtract, 297 mmMultiply, 298 mmAverage 299 }; 300 301 // used in CSound::mixSound() 302 enum SourceFitTypes 303 { 304 sftNone, 305 sftChangeRate, 306 sftChangeTempo 307 }; 308 309 // used in .rez files 310 enum AudioEncodingTypes 311 { 312 // let 0 be invalid 313 aetPCMSigned16BitInteger=1, 314 aetPCM32BitFloat=2, 315 aetPCMSigned8BitInteger=3, 316 aetPCMSigned24BitInteger=4, 317 aetPCMSigned32BitInteger=5 318 }; 319 320 enum Endians 321 { 322 eLittleEndian=0, 323 eBigEndian=1 324 }; 325 326 327 #endif 328