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 }