1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /*************************************************************************** 3 * audiocachefiletest.cc 4 * 5 * Thu Jan 7 15:43:12 CET 2016 6 * Copyright 2016 Bent Bisballe Nyeng 7 * deva@aasimon.org 8 ****************************************************************************/ 9 10 /* 11 * This file is part of DrumGizmo. 12 * 13 * DrumGizmo is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU Lesser General Public License as published by 15 * the Free Software Foundation; either version 3 of the License, or 16 * (at your option) any later version. 17 * 18 * DrumGizmo is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public License 24 * along with DrumGizmo; if not, write to the Free Software 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 26 */ 27 #include <uunit.h> 28 29 #include <cstring> 30 31 #include <audiocachefile.h> 32 #include <audiofile.h> 33 34 #include "drumkit_creator.h" 35 36 class TestableAudioCacheFiles 37 : public AudioCacheFiles 38 { 39 public: 40 //CacheAudioFile& getAudioFile(const std::string& filename); 41 //void release(const std::string& filename); getRef(const std::string & filename)42 int getRef(const std::string& filename) 43 { 44 auto it = audiofiles.find(filename); 45 46 if(it == audiofiles.end()) 47 { 48 return -1; 49 } 50 51 return (it->second).ref; 52 } 53 }; 54 55 class AudioCacheFileTest 56 : public uUnit 57 { 58 public: AudioCacheFileTest()59 AudioCacheFileTest() 60 { 61 uUNIT_TEST(AudioCacheFileTest::refTest); 62 uUNIT_TEST(AudioCacheFileTest::readTest); 63 uUNIT_TEST(AudioCacheFileTest::noFileTest); 64 } 65 66 DrumkitCreator drumkit_creator; 67 refTest()68 void refTest() 69 { 70 // Create the audio file 71 auto filename = drumkit_creator.createSingleChannelWav("single_channel.wav"); 72 73 // Conduct tests 74 TestableAudioCacheFiles audiofiles; 75 uUNIT_ASSERT_EQUAL(-1, audiofiles.getRef(filename)); 76 77 audiofiles.getFile(filename); 78 uUNIT_ASSERT_EQUAL(1, audiofiles.getRef(filename)); 79 80 audiofiles.getFile(filename); 81 uUNIT_ASSERT_EQUAL(2, audiofiles.getRef(filename)); 82 83 audiofiles.releaseFile(filename); 84 uUNIT_ASSERT_EQUAL(1, audiofiles.getRef(filename)); 85 86 audiofiles.releaseFile(filename); 87 uUNIT_ASSERT_EQUAL(-1, audiofiles.getRef(filename)); 88 } 89 readTestHelper(size_t buffer_size)90 void readTestHelper(size_t buffer_size) 91 { 92 printf("Test buffer size: %d samples\n", (int)buffer_size); 93 94 // Create the audio file 95 auto filename = drumkit_creator.createMultiChannelWav("multi_channel.wav"); 96 97 // Conduct tests 98 AudioFile* ref_file[13]; 99 for(size_t c = 0; c < 13; ++c) 100 { 101 ref_file[c] = new AudioFile(filename, c); 102 ref_file[c]->load(nullptr); 103 } 104 105 std::vector<sample_t> read_buffer; 106 107 AudioCacheFile file(filename, read_buffer); 108 uUNIT_ASSERT_EQUAL(filename, file.getFilename()); 109 uUNIT_ASSERT_EQUAL(13, (int)file.getChannelCount()); // Sanity check 110 111 CacheChannels channels; 112 113 sample_t samples[13][buffer_size]; 114 volatile bool ready[13]; 115 for(size_t c = 0; c < 13; ++c) 116 { 117 for(size_t i = 0; i < buffer_size; ++i) 118 { 119 samples[c][i] = 42; 120 } 121 122 channels.push_back( 123 { 124 c, // channel 125 samples[c], // samples 126 buffer_size, // max_num_samples 127 &ready[c] // ready 128 } 129 ); 130 } 131 132 for(size_t offset = 0; offset < file.getSize(); offset += buffer_size) 133 { 134 for(size_t c = 0; c < 13; ++c) 135 { 136 ready[c] = false; 137 } 138 139 size_t read_size = file.getSize() - offset; 140 if(read_size > buffer_size) 141 { 142 read_size = buffer_size; 143 } 144 else 145 { 146 printf("Last read: %d samples\n", (int)read_size); 147 } 148 149 file.readChunk(channels, offset, read_size); 150 151 for(size_t c = 0; c < 13; ++c) 152 { 153 uUNIT_ASSERT_EQUAL(true, ready[c]?true:false); 154 } 155 156 sample_t diff[13] = {0.0}; 157 for(size_t c = 0; c < 13; ++c) 158 { 159 for(size_t i = 0; i < read_size; ++i) 160 { 161 diff[c] += abs((long)(ref_file[c]->data[i + offset] - samples[c][i])); 162 } 163 } 164 165 for(int c = 0; c < 13; ++c) 166 { 167 uUNIT_ASSERT_EQUAL((sample_t)0.0, diff[c]); 168 } 169 } 170 171 for(size_t c = 0; c < 13; ++c) 172 { 173 delete ref_file[c]; 174 } 175 } 176 readTest()177 void readTest() 178 { 179 // Exhaustive test for 1...64 180 for(size_t buffer_size = 1; buffer_size < 64; ++buffer_size) 181 { 182 readTestHelper(buffer_size); 183 } 184 185 // Binary test for 64 .. 4096 186 for(size_t buffer_size = 64; buffer_size < 4096; buffer_size *= 2) 187 { 188 readTestHelper(buffer_size); 189 } 190 191 // And some sporadic tests for some "wierd" sizes. 192 for(size_t buffer_size = 65; buffer_size < 4096; buffer_size *= 1.1) 193 { 194 readTestHelper(buffer_size); 195 } 196 } 197 noFileTest()198 void noFileTest() 199 { 200 size_t buffer_size = 64; 201 std::string filename = "kits/no-such-file.wav"; 202 203 std::vector<sample_t> read_buffer; 204 205 AudioCacheFile file(filename, read_buffer); 206 uUNIT_ASSERT_EQUAL(filename, file.getFilename()); 207 uUNIT_ASSERT_EQUAL(0u, (unsigned int)file.getSize()); 208 uUNIT_ASSERT_EQUAL(0u, (unsigned int)file.getChannelCount()); 209 210 CacheChannels channels; 211 212 sample_t samples[13][buffer_size]; 213 volatile bool ready[13]; 214 for(size_t c = 0; c < 13; ++c) 215 { 216 for(size_t i = 0; i < buffer_size; ++i) 217 { 218 samples[c][i] = 42.0f; 219 } 220 221 channels.push_back( 222 { 223 c, // channel 224 samples[c], // samples 225 buffer_size, // max_num_samples 226 &ready[c] // ready 227 } 228 ); 229 } 230 231 for(size_t c = 0; c < 13; ++c) 232 { 233 ready[c] = false; 234 } 235 236 file.readChunk(channels, 0, buffer_size); 237 238 for(size_t c = 0; c < 13; ++c) 239 { 240 uUNIT_ASSERT_EQUAL(false, ready[c]?true:false); 241 } 242 243 for(size_t c = 0; c < 13; ++c) 244 { 245 for(size_t i = 0; i < buffer_size; ++i) 246 { 247 uUNIT_ASSERT_EQUAL(42.0f, samples[c][i]); 248 } 249 } 250 } 251 }; 252 253 // Registers the fixture into the 'registry' 254 static AudioCacheFileTest test; 255