1 /* 2 * libPCM by László Szerémi. 3 * Copyright under Boost License. 4 */ 5 6 module libPCM.types; 7 8 import core.stdc.stdlib; 9 import std.bitmanip; 10 11 import libPCM.common; 12 13 /** 14 * Stores wave data 15 */ 16 public class WaveData{ 17 size_t length; 18 CodecType codecType; 19 float sampleRate; 20 void[] data; 21 ubyte channels; 22 this(size_t length, float sampleRate, CodecType codecType, void[] data, ubyte channels = 1){ 23 this.length = length; 24 this.sampleRate = sampleRate; 25 this.codecType = codecType; 26 this.data = data; 27 this.channels = channels; 28 } 29 this(size_t length, float sampleRate, CodecType codecType, size_t dataLength, ubyte channels = 1){ 30 this.length = length; 31 this.sampleRate = sampleRate; 32 this.codecType = codecType; 33 this.data.length = dataLength * channels; 34 this.channels = channels; 35 } 36 } 37 /** 38 * Stores *.PCM file header data 39 */ 40 41 public struct PCMHeader{ 42 public: 43 uint length; 44 uint length_u; 45 CodecType codecType; 46 ubyte numOfChannels; 47 ubyte aux; ///Stores additional data if needed 48 float sampleRate; 49 ubyte name_l; ///Actual length = value * 4 50 ubyte author_l; ///Actual length = value * 4 51 ubyte copyright_l; ///Actual length = value * 4 52 ubyte comment_l; ///Actual length = value * 4 53 //export char* name, author, copyright, comment; 54 //export void* startOfData; ///Data Layout in file: ch1pkg, ch2pkg, ch1pkg, ch2pkg... Null if individual streams used 55 //export WaveData** waveData; ///Used for individual streams. 56 public this(int length, int length_u, CodecType codecType, ubyte numOfChannels, ubyte aux, float sampleRate){ 57 this.length = length; 58 this.length_u = length_u; 59 this.codecType = codecType; 60 this.numOfChannels = numOfChannels; 61 this.aux = aux; 62 this.sampleRate = sampleRate; 63 } 64 } 65 public struct PCMFile{ 66 public: 67 PCMHeader header; 68 char[] name, author, copyright, comment; 69 WaveData data; 70 public @nogc: 71 void loadTagData(void* tagData){ 72 73 } 74 } 75 /** 76 * *.wav file header DEPRECATED 77 */ 78 public @nogc struct WavHeader{ 79 public: 80 char[4] chunkID; 81 uint chunkSize; 82 char[4] format; 83 char[4] subchunk1ID; 84 uint subchunk1Size; 85 ushort audioFormat; 86 ushort numOfChannels; 87 uint sampleRate; 88 uint byteRate; 89 ushort blockAlign; 90 ushort bitsPerSample; 91 char[4] subchunk2ID; 92 uint subchunk2Size; 93 public @nogc: 94 this(uint subchunk2Size, ushort audioFormat, ushort numOfChannels, ushort blockAlign, ushort bitsPerSample, uint sampleRate, uint byteRate){ 95 chunkID = "RIFF"; 96 format = "WAVE"; 97 subchunk1ID = "fmt "; 98 subchunk2ID = "data"; 99 subchunk1Size = 16; 100 this.subchunk2Size = subchunk2Size; 101 this.audioFormat = audioFormat; 102 this.numOfChannels = numOfChannels; 103 this.blockAlign = blockAlign; 104 this.bitsPerSample = bitsPerSample; 105 this.sampleRate = sampleRate; 106 this.byteRate = byteRate; 107 } 108 } 109 /** 110 * Split mode Wav Header, first part. Split mode allows loading extra data put between the two subchunks. 111 */ 112 public @nogc struct WavHeaderMain{ 113 public: 114 char[4] chunkID; 115 uint chunkSize; 116 char[4] format; 117 public @nogc this(uint chunkSize){ 118 chunkID = "RIFF"; 119 format = "WAVE"; 120 this.chunkSize = chunkSize; 121 } 122 } 123 /** 124 * Split mode Wav Header, Subchunk1. 125 */ 126 public @nogc struct WavHeaderSubchunk1{ 127 public: 128 char[4] subchunk1ID; 129 uint subchunk1Size; 130 ushort audioFormat; 131 ushort numOfChannels; 132 uint sampleRate; 133 uint byteRate; 134 ushort blockAlign; 135 ushort bitsPerSample; 136 public @nogc this(ushort audioFormat, ushort numOfChannels, ushort blockAlign, ushort bitsPerSample, uint sampleRate, uint byteRate, uint subchunk1Size = 16){ 137 subchunk1ID = "fmt "; 138 //subchunk1Size = 16; 139 this.subchunk1Size = subchunk1Size; 140 this.audioFormat = audioFormat; 141 this.numOfChannels = numOfChannels; 142 this.blockAlign = blockAlign; 143 this.bitsPerSample = bitsPerSample; 144 this.sampleRate = sampleRate; 145 this.byteRate = byteRate; 146 } 147 } 148 /** 149 * Split mode Wav Header, Subchunk2. 150 */ 151 public @nogc struct WavHeaderSubchunk2{ 152 public: 153 char[4] subchunk2ID; 154 uint subchunk2Size; 155 public @nogc this(uint subchunk2Size){ 156 subchunk2ID = "data"; 157 this.subchunk2Size = subchunk2Size; 158 } 159 } 160 /** 161 * *.wav file container. Currently doesn't support extra data stored between subchunk1 and subchunk2. 162 */ 163 public class WavFile{ 164 public: 165 WavHeaderMain riff; 166 WavHeaderSubchunk1 subchunk1; 167 WavHeaderSubchunk2 subchunk2; 168 WaveData data; 169 public this(){ 170 riff = WavHeaderMain(); 171 subchunk1 = WavHeaderSubchunk1(); 172 subchunk2 = WavHeaderSubchunk2(); 173 } 174 } 175 /** 176 * XA ADPCM file header. Please note that certain containers can specify sample rates different than the standard, 177 * which will break the compatibility. 178 */ 179 public @nogc struct XAADPCMHeader{ 180 public ubyte fileNumber; 181 public ubyte channelNumber; 182 //public ubyte subMode; 183 //public ubyte codingInfo; 184 mixin(bitfields!( 185 bool, "EOR" , 1, 186 bool, "Video", 1, 187 bool, "Audio", 1, 188 bool, "Data", 1, 189 bool, "Trigger", 1, 190 bool, "Form", 1, 191 bool, "RealTimeSector", 1, 192 bool, "EOF", 1, 193 uint, "MonoStereo", 2, 194 uint, "SampleRate", 2, 195 uint, "BitsPerSample", 2, 196 bool, "Emphasis", 1, 197 bool, "Reserved", 1, 198 )); 199 200 public @nogc this(ubyte fileNumber, ubyte channelNumber){ 201 202 } 203 } 204 public class AIFFHeader{ 205 public struct Form{ 206 public char[4] chunkID; 207 public uint fileSize; 208 public char[4] fileType; 209 } 210 public struct Comm{ 211 public char[4] chunkID; 212 public uint chunkSize; 213 public ushort numOfChannels; 214 public ushort numOfFramesL; 215 public ushort numOfFramesH; 216 public ushort bitsPerSample; 217 public real sampleRate; 218 } 219 public struct Ssnd{ 220 public char[4] chunkID; 221 public uint chunkSize; 222 public uint offset; ///Comment Length 223 public uint blockSize; 224 } 225 string comment; 226 }