1 |
#include "GigWriteTest.h" |
2 |
|
3 |
#include <iostream> |
4 |
#include <stdlib.h> |
5 |
#include <stdio.h> |
6 |
#include <string.h> |
7 |
|
8 |
#include "../gig.h" |
9 |
#include "../helper.h" |
10 |
|
11 |
CPPUNIT_TEST_SUITE_REGISTRATION(GigWriteTest); |
12 |
|
13 |
using namespace std; |
14 |
|
15 |
// file name of the Gigasampler file we are going to create for these tests |
16 |
#define TEST_GIG_FILE_NAME "foo.gig" |
17 |
|
18 |
// four stupid little sample "waves" |
19 |
// (each having three sample points length, 16 bit depth, mono) |
20 |
int16_t sampleData1[] = { 1, 2, 3 }; |
21 |
int16_t sampleData2[] = { 4, 5, 6 }; |
22 |
int16_t sampleData3[] = { 7, 8, 9 }; |
23 |
int16_t sampleData4[] = { 10,11,12 }; |
24 |
|
25 |
// 1. Run) print the purpose of this test case first |
26 |
void GigWriteTest::printTestSuiteName() { |
27 |
cout << "\b \nTesting Gigasampler write support: " << flush; |
28 |
} |
29 |
|
30 |
// code executed when this test suite is created |
31 |
void GigWriteTest::setUp() { |
32 |
} |
33 |
|
34 |
// code executed when this test suite will be destroyed |
35 |
void GigWriteTest::tearDown() { |
36 |
} |
37 |
|
38 |
|
39 |
///////////////////////////////////////////////////////////////////////////// |
40 |
// The actual test cases (in order) ... |
41 |
|
42 |
// 2. Run) create a new Gigasampler file from scratch |
43 |
void GigWriteTest::createNewGigFile() { |
44 |
try { |
45 |
// create an empty Gigasampler file |
46 |
gig::File file; |
47 |
// we give it an internal name, not mandatory though |
48 |
file.pInfo->Name = "Foo Gigasampler File"; |
49 |
|
50 |
// create four samples |
51 |
gig::Sample* pSample1 = file.AddSample(); |
52 |
gig::Sample* pSample2 = file.AddSample(); |
53 |
gig::Sample* pSample3 = file.AddSample(); |
54 |
gig::Sample* pSample4 = file.AddSample(); |
55 |
// give those samples a name (not mandatory) |
56 |
pSample1->pInfo->Name = "Foo Sample 1"; |
57 |
pSample2->pInfo->Name = "Foo Sample 2"; |
58 |
pSample3->pInfo->Name = "Foo Sample 3"; |
59 |
pSample4->pInfo->Name = "Foo Sample 4"; |
60 |
// set meta informations for those samples |
61 |
pSample1->Channels = 1; // mono |
62 |
pSample1->BitDepth = 16; // 16 bits |
63 |
pSample1->FrameSize = 16/*bitdepth*/ / 8/*1 byte are 8 bits*/ * 1/*mono*/; |
64 |
pSample1->SamplesPerSecond = 44100; |
65 |
pSample2->Channels = 1; // mono |
66 |
pSample2->BitDepth = 16; // 16 bits |
67 |
pSample2->FrameSize = 16 / 8 * 1; |
68 |
pSample2->SamplesPerSecond = 44100; |
69 |
pSample3->Channels = 1; // mono |
70 |
pSample3->BitDepth = 16; // 16 bits |
71 |
pSample3->FrameSize = 16 / 8 * 1; |
72 |
pSample3->SamplesPerSecond = 44100; |
73 |
pSample4->Channels = 1; // mono |
74 |
pSample4->BitDepth = 16; // 16 bits |
75 |
pSample4->FrameSize = 16 / 8 * 1; |
76 |
pSample4->SamplesPerSecond = 44100; |
77 |
// resize those samples to a length of three sample points |
78 |
// (again: _sample_points_ NOT bytes!) which is the length of our |
79 |
// ficticious samples from above. after the Save() call below we can |
80 |
// then directly write our sample data to disk by using the Write() |
81 |
// method, that is without having to load all the sample data into |
82 |
// RAM. for large instruments / .gig files this is definitely the way |
83 |
// to go |
84 |
pSample1->Resize(3); |
85 |
pSample2->Resize(3); |
86 |
pSample3->Resize(3); |
87 |
pSample4->Resize(3); |
88 |
|
89 |
// create four instruments |
90 |
gig::Instrument* pInstrument1 = file.AddInstrument(); |
91 |
gig::Instrument* pInstrument2 = file.AddInstrument(); |
92 |
gig::Instrument* pInstrument3 = file.AddInstrument(); |
93 |
gig::Instrument* pInstrument4 = file.AddInstrument(); |
94 |
// give them a name (not mandatory) |
95 |
pInstrument1->pInfo->Name = "Foo Instrument 1"; |
96 |
pInstrument2->pInfo->Name = "Foo Instrument 2"; |
97 |
pInstrument3->pInfo->Name = "Foo Instrument 3"; |
98 |
pInstrument4->pInfo->Name = "Foo Instrument 4"; |
99 |
|
100 |
// create one region for each instrument |
101 |
// in this example we do not add a dimension, so |
102 |
// every region will have exactly one DimensionRegion |
103 |
// also we assign a sample to each dimension region |
104 |
gig::Region* pRegion = pInstrument1->AddRegion(); |
105 |
pRegion->SetSample(pSample1); |
106 |
pRegion->KeyRange.low = 0; |
107 |
pRegion->KeyRange.high = 1; |
108 |
pRegion->VelocityRange.low = 0; |
109 |
pRegion->VelocityRange.high = 1; |
110 |
pRegion->KeyGroup = 0; |
111 |
pRegion->pDimensionRegions[0]->pSample = pSample1; |
112 |
|
113 |
pRegion = pInstrument2->AddRegion(); |
114 |
pRegion->SetSample(pSample2); |
115 |
pRegion->KeyRange.low = 1; |
116 |
pRegion->KeyRange.high = 2; |
117 |
pRegion->VelocityRange.low = 1; |
118 |
pRegion->VelocityRange.high = 2; |
119 |
pRegion->KeyGroup = 1; |
120 |
pRegion->pDimensionRegions[0]->pSample = pSample2; |
121 |
|
122 |
pRegion = pInstrument3->AddRegion(); |
123 |
pRegion->SetSample(pSample3); |
124 |
pRegion->KeyRange.low = 2; |
125 |
pRegion->KeyRange.high = 3; |
126 |
pRegion->VelocityRange.low = 2; |
127 |
pRegion->VelocityRange.high = 3; |
128 |
pRegion->KeyGroup = 2; |
129 |
pRegion->pDimensionRegions[0]->pSample = pSample3; |
130 |
|
131 |
pRegion = pInstrument4->AddRegion(); |
132 |
pRegion->SetSample(pSample4); |
133 |
pRegion->KeyRange.low = 3; |
134 |
pRegion->KeyRange.high = 4; |
135 |
pRegion->VelocityRange.low = 3; |
136 |
pRegion->VelocityRange.high = 4; |
137 |
pRegion->KeyGroup = 3; |
138 |
pRegion->pDimensionRegions[0]->pSample = pSample4; |
139 |
|
140 |
// save file ("physically") as of now |
141 |
file.Save(TEST_GIG_FILE_NAME); |
142 |
} catch (RIFF::Exception e) { |
143 |
std::cerr << "\nCould not create a new Gigasampler file from scratch:\n" << std::flush; |
144 |
e.PrintMessage(); |
145 |
throw e; // stop further tests |
146 |
} |
147 |
} |
148 |
|
149 |
// 3. Run) test if the newly created Gigasampler file exists & can be opened |
150 |
void GigWriteTest::testOpenCreatedGigFile() { |
151 |
// try to open previously created Gigasampler file |
152 |
try { |
153 |
RIFF::File riff(TEST_GIG_FILE_NAME); |
154 |
gig::File file(&riff); |
155 |
} catch (RIFF::Exception e) { |
156 |
std::cerr << "\nCould not open newly created Gigasampler file:\n" << std::flush; |
157 |
e.PrintMessage(); |
158 |
throw e; // stop further tests |
159 |
} |
160 |
} |
161 |
|
162 |
// 4. Run) test if the articulation informations of the newly created Gigasampler file were correctly written |
163 |
void GigWriteTest::testArticulationsOfCreatedGigFile() { |
164 |
try { |
165 |
// open previously created Gigasampler file |
166 |
RIFF::File riff(TEST_GIG_FILE_NAME); |
167 |
gig::File file(&riff); |
168 |
// check global file informations |
169 |
CPPUNIT_ASSERT(file.pInfo); |
170 |
CPPUNIT_ASSERT(file.pInfo->Name == "Foo Gigasampler File"); |
171 |
// check amount of instruments and samples |
172 |
CPPUNIT_ASSERT(file.Instruments == 4); |
173 |
int iInstruments = 0; |
174 |
for (gig::Instrument* pInstrument = file.GetFirstInstrument(); pInstrument; pInstrument = file.GetNextInstrument()) iInstruments++; |
175 |
CPPUNIT_ASSERT(iInstruments == 4); |
176 |
int iSamples = 0; |
177 |
for (gig::Sample* pSample = file.GetFirstSample(); pSample; pSample = file.GetNextSample()) iSamples++; |
178 |
CPPUNIT_ASSERT(iSamples == 4); |
179 |
// check samples' meta informations |
180 |
int iSample = 1; |
181 |
for (gig::Sample* pSample = file.GetFirstSample(); pSample; pSample = file.GetNextSample()) { |
182 |
CPPUNIT_ASSERT(pSample->pInfo); |
183 |
std::string sOughtToBe = "Foo Sample " + ToString(iSample); |
184 |
CPPUNIT_ASSERT(pSample->pInfo->Name == sOughtToBe); |
185 |
CPPUNIT_ASSERT(pSample->GetSize() == 3); // three sample points |
186 |
CPPUNIT_ASSERT(pSample->SamplesTotal == 3); // three sample points |
187 |
CPPUNIT_ASSERT(pSample->Channels == 1); // mono |
188 |
CPPUNIT_ASSERT(pSample->BitDepth == 16); // bit depth 16 bits |
189 |
CPPUNIT_ASSERT(pSample->FrameSize == 16 / 8 * 1); |
190 |
CPPUNIT_ASSERT(pSample->SamplesPerSecond == 44100); |
191 |
iSample++; |
192 |
} |
193 |
// check instruments' meta informations |
194 |
int iInstrument = 1; |
195 |
for (gig::Instrument* pInstrument = file.GetFirstInstrument(); pInstrument; pInstrument = file.GetNextInstrument()) { |
196 |
CPPUNIT_ASSERT(pInstrument->pInfo); |
197 |
std::string sOughtToBe = "Foo Instrument " + ToString(iInstrument); |
198 |
CPPUNIT_ASSERT(pInstrument->pInfo->Name == sOughtToBe); |
199 |
gig::Region* pRegion = pInstrument->GetFirstRegion(); |
200 |
CPPUNIT_ASSERT(pRegion); |
201 |
CPPUNIT_ASSERT(pRegion->Dimensions == 0); |
202 |
CPPUNIT_ASSERT(pRegion->DimensionRegions == 1); |
203 |
sOughtToBe = "Foo Sample " + ToString(iInstrument); |
204 |
CPPUNIT_ASSERT(pRegion->GetSample()->pInfo->Name == sOughtToBe); |
205 |
CPPUNIT_ASSERT(pRegion->KeyRange.low == iInstrument - 1); |
206 |
CPPUNIT_ASSERT(pRegion->KeyRange.high == iInstrument); |
207 |
CPPUNIT_ASSERT(pRegion->VelocityRange.low == iInstrument - 1); |
208 |
CPPUNIT_ASSERT(pRegion->VelocityRange.high == iInstrument); |
209 |
CPPUNIT_ASSERT(pRegion->KeyGroup == iInstrument - 1); |
210 |
const uint dimValues[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
211 |
gig::DimensionRegion* pDimensionRegion = pRegion->GetDimensionRegionByValue(dimValues); |
212 |
CPPUNIT_ASSERT(pDimensionRegion); |
213 |
CPPUNIT_ASSERT(pDimensionRegion->pSample->pInfo->Name == sOughtToBe); |
214 |
iInstrument++; |
215 |
} |
216 |
} catch (RIFF::Exception e) { |
217 |
std::cerr << "\nThere was an exception while checking the articulation data of the newly created Gigasampler file:\n" << std::flush; |
218 |
e.PrintMessage(); |
219 |
throw e; // stop further tests |
220 |
} |
221 |
} |
222 |
|
223 |
// 5. Run) try to write sample data to that newly created Gigasampler file |
224 |
void GigWriteTest::testWriteSamples() { |
225 |
try { |
226 |
// open previously created Gigasampler file (in read/write mode) |
227 |
RIFF::File riff(TEST_GIG_FILE_NAME); |
228 |
riff.SetMode(RIFF::stream_mode_read_write); |
229 |
gig::File file(&riff); |
230 |
// until this point we just wrote the articulation data to the .gig file |
231 |
// and prepared the .gig file for writing our 4 example sample data, so |
232 |
// now as the file exists physically and the 'samples' are already |
233 |
// of the correct size we can now write the actual samples' data by |
234 |
// directly writing them to disk |
235 |
gig::Sample* pSample1 = file.GetFirstSample(); |
236 |
gig::Sample* pSample2 = file.GetNextSample(); |
237 |
gig::Sample* pSample3 = file.GetNextSample(); |
238 |
gig::Sample* pSample4 = file.GetNextSample(); |
239 |
CPPUNIT_ASSERT(pSample1); |
240 |
pSample1->Write(sampleData1, 3); |
241 |
CPPUNIT_ASSERT(pSample2); |
242 |
pSample2->Write(sampleData2, 3); |
243 |
CPPUNIT_ASSERT(pSample3); |
244 |
pSample3->Write(sampleData3, 3); |
245 |
CPPUNIT_ASSERT(pSample4); |
246 |
pSample4->Write(sampleData4, 3); |
247 |
} catch (RIFF::Exception e) { |
248 |
std::cerr << "\nCould not directly write samples to newly created Gigasampler file:\n" << std::flush; |
249 |
e.PrintMessage(); |
250 |
throw e; // stop further tests |
251 |
} |
252 |
} |
253 |
|
254 |
// 6. Run) check the previously written samples' data |
255 |
void GigWriteTest::testSamplesData() { |
256 |
try { |
257 |
// open previously created Gigasampler file |
258 |
RIFF::File riff(TEST_GIG_FILE_NAME); |
259 |
gig::File file(&riff); |
260 |
// check samples' meta informations |
261 |
gig::Sample* pSample1 = file.GetFirstSample(); |
262 |
gig::Sample* pSample2 = file.GetNextSample(); |
263 |
gig::Sample* pSample3 = file.GetNextSample(); |
264 |
gig::Sample* pSample4 = file.GetNextSample(); |
265 |
CPPUNIT_ASSERT(pSample1); |
266 |
CPPUNIT_ASSERT(pSample2); |
267 |
CPPUNIT_ASSERT(pSample3); |
268 |
CPPUNIT_ASSERT(pSample4); |
269 |
gig::buffer_t sampleBuffer1 = pSample1->LoadSampleData(); |
270 |
gig::buffer_t sampleBuffer2 = pSample2->LoadSampleData(); |
271 |
gig::buffer_t sampleBuffer3 = pSample3->LoadSampleData(); |
272 |
gig::buffer_t sampleBuffer4 = pSample4->LoadSampleData(); |
273 |
CPPUNIT_ASSERT(sampleBuffer1.pStart); |
274 |
CPPUNIT_ASSERT(sampleBuffer2.pStart); |
275 |
CPPUNIT_ASSERT(sampleBuffer3.pStart); |
276 |
CPPUNIT_ASSERT(sampleBuffer4.pStart); |
277 |
CPPUNIT_ASSERT(sampleBuffer1.Size == pSample1->FrameSize * 3); // three sample points length |
278 |
CPPUNIT_ASSERT(sampleBuffer2.Size == pSample2->FrameSize * 3); // three sample points length |
279 |
CPPUNIT_ASSERT(sampleBuffer3.Size == pSample3->FrameSize * 3); // three sample points length |
280 |
CPPUNIT_ASSERT(sampleBuffer4.Size == pSample4->FrameSize * 3); // three sample points length |
281 |
// check samples' PCM data |
282 |
CPPUNIT_ASSERT(memcmp(sampleBuffer1.pStart, sampleData1, 3) == 0); |
283 |
CPPUNIT_ASSERT(memcmp(sampleBuffer2.pStart, sampleData2, 3) == 0); |
284 |
CPPUNIT_ASSERT(memcmp(sampleBuffer3.pStart, sampleData3, 3) == 0); |
285 |
CPPUNIT_ASSERT(memcmp(sampleBuffer4.pStart, sampleData4, 3) == 0); |
286 |
} catch (RIFF::Exception e) { |
287 |
std::cerr << "\nThere was an exception while checking the written samples' data:\n" << std::flush; |
288 |
e.PrintMessage(); |
289 |
throw e; // stop further tests |
290 |
} |
291 |
} |