1 /* 2 * libPCM by László Szerémi. 3 * Copyright under Boost License. 4 */ 5 6 module libPCM.common; 7 8 import core.stdc.stdlib; 9 10 import libPCM.types; 11 12 /** 13 * Describes the type of codec used, as well as the bitdepth 14 */ 15 public enum CodecType : ushort{ 16 NULL = 0, 17 UNSIGNED8BIT = 1, 18 UNSIGNED12BIT = 2, 19 UNSIGNED16BIT = 3, 20 UNSIGNED24BIT = 4, 21 UNSIGNED32BIT = 5, 22 SIGNED8BIT = 6, 23 SIGNED12BIT = 7, 24 SIGNED16BIT = 8, 25 SIGNED24BIT = 9, 26 SIGNED32BIT = 10, 27 DIALOGIC_ADPCM = 32, 28 IMA_ADPCM = 33, 29 XA_ADPCM = 35, 30 Yamaha_ADPCMA = 36, 31 MU_LAW = 64, 32 A_LAW_87_6 = 65, 33 FLOAT = 96, 34 } 35 36 /** 37 * For *.wav files 38 */ 39 public enum WAVAudioFormat : ushort{ 40 /* WAVE form wFormatTag IDs */ 41 UNKNOWN = 0x0000, /* Microsoft Corporation */ 42 PCM = 0x0001, 43 ADPCM = 0x0002, /* Microsoft Corporation */ 44 IEEE_FLOAT = 0x0003, /* Microsoft Corporation */ 45 VSELP = 0x0004, /* Compaq Computer Corp. */ 46 IBM_CVSD = 0x0005, /* IBM Corporation */ 47 ALAW = 0x0006, /* Microsoft Corporation */ 48 MULAW = 0x0007, /* Microsoft Corporation */ 49 DTS = 0x0008, /* Microsoft Corporation */ 50 OKI_ADPCM = 0x0010, /* OKI */ 51 DVI_ADPCM = 0x0011, /* Intel Corporation */ 52 IMA_ADPCM = DVI_ADPCM, /* Intel Corporation */ 53 MEDIASPACE_ADPCM = 0x0012, /* Videologic */ 54 SIERRA_ADPCM= 0x0013, /* Sierra Semiconductor Corp */ 55 G723_ADPCM = 0x0014, /* Antex Electronics Corporation */ 56 DIGISTD = 0x0015, /* DSP Solutions, Inc. */ 57 DIGIFIX = 0x0016, /* DSP Solutions, Inc. */ 58 DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic Corporation */ 59 MEDIAVISION_ADPCM = 0x0018, /* Media Vision, Inc. */ 60 CU_CODEC = 0x0019, /* Hewlett-Packard Company */ 61 YAMAHA_ADPCM= 0x0020, /* Yamaha Corporation of America */ 62 SONARC = 0x0021, /* Speech Compression */ 63 DSPGROUP_TRUESPEECH = 0x0022, /* DSP Group, Inc */ 64 ECHOSC1 = 0x0023, /* Echo Speech Corporation */ 65 AUDIOFILE_AF36 = 0x0024, /* Virtual Music, Inc. */ 66 APTX = 0x0025, /* Audio Processing Technology */ 67 AUDIOFILE_AF10 = 0x0026, /* Virtual Music, Inc. */ 68 PROSODY_1612= 0x0027, /* Aculab plc */ 69 LRC = 0x0028, /* Merging Technologies S.A. */ 70 DOLBY_AC2 = 0x0030, /* Dolby Laboratories */ 71 GSM610 = 0x0031, /* Microsoft Corporation */ 72 MSNAUDIO = 0x0032, /* Microsoft Corporation */ 73 ANTEX_ADPCME= 0x0033, /* Antex Electronics Corporation */ 74 CONTROL_RES_VQLPC = 0x0034, /* Control Resources Limited */ 75 DIGIREAL = 0x0035, /* DSP Solutions, Inc. */ 76 DIGIADPCM = 0x0036, /* DSP Solutions, Inc. */ 77 CONTROL_RES_CR10 = 0x0037, /* Control Resources Limited */ 78 NMS_VBXADPCM= 0x0038, /* Natural MicroSystems */ 79 CS_IMAADPCM = 0x0039, /* Crystal Semiconductor IMA ADPCM */ 80 ECHOSC3 = 0x003A, /* Echo Speech Corporation */ 81 ROCKWELL_ADPCM = 0x003B, /* Rockwell International */ 82 ROCKWELL_DIGITALK = 0x003C, /* Rockwell International */ 83 XEBEC = 0x003D, /* Xebec Multimedia Solutions Limited */ 84 G721_ADPCM = 0x0040, /* Antex Electronics Corporation */ 85 G728_CELP = 0x0041, /* Antex Electronics Corporation */ 86 MSG723 = 0x0042, /* Microsoft Corporation */ 87 MPEG = 0x0050, /* Microsoft Corporation */ 88 RT24 = 0x0052, /* InSoft, Inc. */ 89 PAC = 0x0053, /* InSoft, Inc. */ 90 MPEGLAYER3 = 0x0055, /* ISO/MPEG Layer3 Format Tag */ 91 LUCENT_G723 = 0x0059, /* Lucent Technologies */ 92 CIRRUS = 0x0060, /* Cirrus Logic */ 93 ESPCM = 0x0061, /* ESS Technology */ 94 VOXWARE = 0x0062, /* Voxware Inc */ 95 CANOPUS_ATRAC = 0x0063, /* Canopus, co., Ltd. */ 96 G726_ADPCM = 0x0064, /* APICOM */ 97 G722_ADPCM = 0x0065, /* APICOM */ 98 DSAT_DISPLAY= 0x0067, /* Microsoft Corporation */ 99 VOXWARE_BYTE_ALIGNED= 0x0069, /* Voxware Inc */ 100 VOXWARE_AC8 = 0x0070, /* Voxware Inc */ 101 VOXWARE_AC10= 0x0071, /* Voxware Inc */ 102 VOXWARE_AC16= 0x0072, /* Voxware Inc */ 103 VOXWARE_AC20= 0x0073, /* Voxware Inc */ 104 VOXWARE_RT24= 0x0074, /* Voxware Inc */ 105 VOXWARE_RT29= 0x0075, /* Voxware Inc */ 106 VOXWARE_RT29HW = 0x0076, /* Voxware Inc */ 107 VOXWARE_VR12= 0x0077, /* Voxware Inc */ 108 VOXWARE_VR18= 0x0078, /* Voxware Inc */ 109 VOXWARE_TQ40= 0x0079, /* Voxware Inc */ 110 SOFTSOUND = 0x0080, /* Softsound, Ltd. */ 111 VOXWARE_TQ60= 0x0081, /* Voxware Inc */ 112 MSRT24 = 0x0082, /* Microsoft Corporation */ 113 G729A = 0x0083, /* AT&T Labs, Inc. */ 114 MVI_MVI2 = 0x0084, /* Motion Pixels */ 115 DF_G726 = 0x0085, /* DataFusion Systems (Pty) (Ltd) */ 116 DF_GSM610 = 0x0086, /* DataFusion Systems (Pty) (Ltd) */ 117 ISIAUDIO = 0x0088, /* Iterated Systems, Inc. */ 118 ONLIVE = 0x0089, /* OnLive! Technologies, Inc. */ 119 SBC24 = 0x0091, /* Siemens Business Communications Sys */ 120 DOLBY_AC3_SPDIF = 0x0092, /* Sonic Foundry */ 121 MEDIASONIC_G723 = 0x0093, /* MediaSonic */ 122 PROSODY_8KBPS = 0x0094, /* Aculab plc */ 123 ZYXEL_ADPCM = 0x0097, /* ZyXEL Communications, Inc. */ 124 PHILIPS_LPCBB = 0x0098, /* Philips Speech Processing */ 125 PACKED = 0x0099, /* Studer Professional Audio AG */ 126 MALDEN_PHONYTALK = 0x00A0, /* Malden Electronics Ltd. */ 127 RHETOREX_ADPCM = 0x0100, /* Rhetorex Inc. */ 128 IRAT = 0x0101, /* BeCubed Software Inc. */ 129 VIVO_G723 = 0x0111, /* Vivo Software */ 130 VIVO_SIREN = 0x0112, /* Vivo Software */ 131 DIGITAL_G723= 0x0123, /* Digital Equipment Corporation */ 132 SANYO_LD_ADPCM = 0x0125, /* Sanyo Electric Co., Ltd. */ 133 SIPROLAB_ACEPLNET = 0x0130, /* Sipro Lab Telecom Inc. */ 134 SIPROLAB_ACELP4800 = 0x0131, /* Sipro Lab Telecom Inc. */ 135 SIPROLAB_ACELP8V3 = 0x0132, /* Sipro Lab Telecom Inc. */ 136 SIPROLAB_G729 = 0x0133, /* Sipro Lab Telecom Inc. */ 137 SIPROLAB_G729A = 0x0134, /* Sipro Lab Telecom Inc. */ 138 SIPROLAB_KELVIN = 0x0135, /* Sipro Lab Telecom Inc. */ 139 G726ADPCM = 0x0140, /* Dictaphone Corporation */ 140 QUALCOMM_PUREVOICE = 0x0150, /* Qualcomm, Inc. */ 141 QUALCOMM_HALFRATE = 0x0151, /* Qualcomm, Inc. */ 142 TUBGSM = 0x0155, /* Ring Zero Systems, Inc. */ 143 MSAUDIO1 = 0x0160, /* Microsoft Corporation */ 144 CREATIVE_ADPCM = 0x0200, /* Creative Labs, Inc */ 145 CREATIVE_FASTSPEECH8= 0x0202, /* Creative Labs, Inc */ 146 CREATIVE_FASTSPEECH10 = 0x0203, /* Creative Labs, Inc */ 147 UHER_ADPCM = 0x0210, /* UHER informatic GmbH */ 148 QUARTERDECK = 0x0220, /* Quarterdeck Corporation */ 149 ILINK_VC = 0x0230, /* I-link Worldwide */ 150 RAW_SPORT = 0x0240, /* Aureal Semiconductor */ 151 IPI_HSX = 0x0250, /* Interactive Products, Inc. */ 152 IPI_RPELP = 0x0251, /* Interactive Products, Inc. */ 153 CS2 = 0x0260, /* Consistent Software */ 154 SONY_SCX = 0x0270, /* Sony Corp. */ 155 FM_TOWNS_SND= 0x0300, /* Fujitsu Corp. */ 156 BTV_DIGITAL = 0x0400, /* Brooktree Corporation */ 157 QDESIGN_MUSIC = 0x0450, /* QDesign Corporation */ 158 VME_VMPCM = 0x0680, /* AT&T Labs, Inc. */ 159 TPC = 0x0681, /* AT&T Labs, Inc. */ 160 OLIGSM = 0x1000, /* Ing C. Olivetti & C., S.p.A. */ 161 OLIADPCM = 0x1001, /* Ing C. Olivetti & C., S.p.A. */ 162 OLICELP = 0x1002, /* Ing C. Olivetti & C., S.p.A. */ 163 OLISBC = 0x1003, /* Ing C. Olivetti & C., S.p.A. */ 164 OLIOPR = 0x1004, /* Ing C. Olivetti & C., S.p.A. */ 165 LH_CODEC = 0x1100, /* Lernout & Hauspie */ 166 WAVE_FORMAT_NORRIS = 0x1400, /* Norris Communications, Inc. */ 167 SOUNDSPACE_MUSICOMPRESS = 0x1500, /* AT&T Labs, Inc. */ 168 DVM = 0x2000, /* FAST Multimedia AG */ 169 } 170 171 public CodecType fromWAVAudioFormat(ushort input, ushort bitDepth){ 172 switch(input){ 173 case WAVAudioFormat.PCM: 174 switch (bitDepth){ 175 case 8: 176 return CodecType.UNSIGNED8BIT; 177 case 16: 178 return CodecType.SIGNED16BIT; 179 default: 180 return CodecType.NULL; 181 } 182 case WAVAudioFormat.OKI_ADPCM: 183 return CodecType.DIALOGIC_ADPCM; 184 case WAVAudioFormat.IMA_ADPCM: 185 return CodecType.IMA_ADPCM; 186 case WAVAudioFormat.IEEE_FLOAT: 187 return CodecType.FLOAT; 188 default: 189 return CodecType.NULL; 190 } 191 } 192 193 public class AudioFileException : Exception{ 194 @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) 195 { 196 super(msg, file, line, next); 197 } 198 199 @nogc @safe pure nothrow this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) 200 { 201 super(msg, file, line, next); 202 } 203 } 204 205 206 /** 207 * Returns the word lenght for the given codec type 208 */ 209 public @nogc int getWordLength(CodecType codec){ 210 switch(codec){ 211 //case CodecType.A_LAW_87_6, CodecType.MU_LAW, CodecType.SIGNED8BIT, CodecType.UNSIGNED8BIT: return 8; 212 //case CodecType.DIALOGIC_ADPCM, CodecType.IMA_ADPCM: return 4; 213 case CodecType.SIGNED16BIT, CodecType.UNSIGNED16BIT: return 16; 214 case CodecType.SIGNED24BIT, CodecType.UNSIGNED24BIT: return 24; 215 case CodecType.SIGNED32BIT, CodecType.UNSIGNED32BIT, CodecType.FLOAT: return 32; 216 //case CodecType.COMPACT_ADPCM: return 2; 217 case CodecType.XA_ADPCM: return 128 * 8; 218 default: return 8; 219 } 220 } 221 /** 222 * Completely deallocates the memory for the given PCM data 223 */ 224 /*void deletePCMFromMemory(PCMFile* file){ 225 if(file.name){ 226 free(file.name); 227 } 228 if(file.startOfData){ 229 free(file.startOfData); 230 }else{ 231 for(int i ; i < file.header.numOfChannels ; i++){ 232 free((*file.waveData + i).data); 233 free(file.waveData + i); 234 } 235 } 236 free(file); 237 }*/ 238 /** 239 * Separates audio streams from a joint stream. 240 */ 241 public @nogc void separateAudioChannels(void* input, void*[8] output, uint lenght, int channels, int wordLength = 16){ 242 switch(wordLength){ 243 case 16: 244 ushort* input0 = cast(ushort*)input; 245 ushort*[8] output0 = cast(ushort*[8])output; 246 for(uint i ; i < lenght ; i++){ 247 for(int j ; j < channels ; j++){ 248 output0[j][i] = input0[(i * channels) + j]; 249 } 250 } 251 break; 252 case 8: 253 ubyte* input0 = cast(ubyte*)input; 254 ubyte*[8] output0 = cast(ubyte*[8])output; 255 for(uint i ; i < lenght ; i++){ 256 for(int j ; j < channels ; j++){ 257 output0[j][i] = input0[(i * channels) + j]; 258 } 259 } 260 break; 261 case 32: 262 uint* input0 = cast(uint*)input; 263 uint*[8] output0 = cast(uint*[8])output; 264 for(uint i ; i < lenght ; i++){ 265 for(int j ; j < channels ; j++){ 266 output0[j][i] = input0[(i * channels) + j]; 267 } 268 } 269 break; 270 default: 271 if(!(wordLength % 8)){ 272 ubyte* input0 = cast(ubyte*)input; 273 ubyte*[8] output0 = cast(ubyte*[8])output; 274 for(uint i ; i < lenght ; i++){ 275 for(int j ; j < channels ; j++){ 276 for(int k ; k < wordLength / 8 ; k++){ 277 output0[j][i+k] = input0[(i * channels) + j + k]; 278 } 279 } 280 } 281 } 282 break; 283 } 284 } 285 /** 286 * Joints multiple audio channels into a single one. 287 */ 288 public @nogc void joinAudioChannels(void*[8] input, void* output, uint lenght, int channels, int wordLength = 16){ 289 switch(wordLength){ 290 case 16: 291 ushort* output0 = cast(ushort*)output; 292 ushort*[8] input0 = cast(ushort*[8])input; 293 for(uint i ; i < lenght ; i++){ 294 for(int j ; j < channels ; j++){ 295 output0[(i * channels) + j] = input0[j][i]; 296 } 297 } 298 break; 299 case 8: 300 ubyte* output0 = cast(ubyte*)output; 301 ubyte*[8] input0 = cast(ubyte*[8])input; 302 for(uint i ; i < lenght ; i++){ 303 for(int j ; j < channels ; j++){ 304 output0[(i * channels) + j] = input0[j][i]; 305 } 306 } 307 break; 308 case 32: 309 uint* output0 = cast(uint*)output; 310 uint*[8] input0 = cast(uint*[8])input; 311 for(uint i ; i < lenght ; i++){ 312 for(int j ; j < channels ; j++){ 313 output0[(i * channels) + j] = input0[j][i]; 314 } 315 } 316 break; 317 default: 318 if(!(wordLength % 8)){ 319 ubyte* output0 = cast(ubyte*)output; 320 ubyte*[8] input0 = cast(ubyte*[8])input; 321 for(uint i ; i < lenght ; i++){ 322 for(int j ; j < channels ; j++){ 323 for(int k ; k < wordLength / 8 ; k++){ 324 output0[(i * channels) + j + k] = input0[j][i+k]; 325 } 326 } 327 } 328 } 329 break; 330 } 331 }