1 /* 2 DSFML - The Simple and Fast Multimedia Library for D 3 4 Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com) 5 6 This software is provided 'as-is', without any express or implied warranty. 7 In no event will the authors be held liable for any damages arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, including commercial applications, 10 and to alter it and redistribute it freely, subject to the following restrictions: 11 12 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. 13 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 14 15 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 16 17 3. This notice may not be removed or altered from any source distribution 18 */ 19 20 module dsfml.audio.soundfile; 21 22 import std.string; 23 import dsfml.system.inputstream; 24 import dsfml.system.err; 25 26 package: 27 28 struct SoundFile 29 { 30 private sfSoundFile* m_soundFile; 31 private soundFileStream m_stream;//keeps an instance of the C++ interface stored if used 32 33 void create() 34 { 35 m_soundFile = sfSoundFile_create(); 36 } 37 38 ~this() 39 { 40 sfSoundFile_destroy(m_soundFile); 41 } 42 43 bool openReadFromFile(string filename) 44 { 45 import dsfml.system.string; 46 bool toReturn = sfSoundFile_openReadFromFile(m_soundFile, toStringz(filename)); 47 err.write(toString(sfErr_getOutput())); 48 return toReturn; 49 } 50 51 bool openReadFromMemory(const(void)[] data) 52 { 53 import dsfml.system.string; 54 bool toReturn = sfSoundFile_openReadFromMemory(m_soundFile, data.ptr, data.length); 55 err.write(toString(sfErr_getOutput())); 56 return toReturn; 57 } 58 bool openReadFromStream(InputStream stream) 59 { 60 import dsfml.system.string; 61 m_stream = new soundFileStream(stream); 62 63 bool toReturn = sfSoundFile_openReadFromStream(m_soundFile, m_stream); 64 err.write(toString(sfErr_getOutput())); 65 return toReturn; 66 } 67 68 bool openWrite(string filename,uint channelCount,uint sampleRate) 69 { 70 import dsfml.system.string; 71 bool toReturn = sfSoundFile_openWrite(m_soundFile, toStringz(filename),channelCount,sampleRate); 72 err.write(toString(sfErr_getOutput())); 73 return toReturn; 74 } 75 76 long read(ref short[] data) 77 { 78 return sfSoundFile_read(m_soundFile,data.ptr, data.length); 79 80 } 81 82 void write(const(short)[] data) 83 { 84 sfSoundFile_write(m_soundFile, data.ptr, data.length); 85 } 86 87 void seek(long timeOffset) 88 { 89 import dsfml.system.string; 90 sfSoundFile_seek(m_soundFile, timeOffset); 91 92 //Temporary fix for a bug where attempting to write to err 93 //throws an exception in a thread created in C++. This causes 94 //the program to explode. Hooray. 95 96 //This fix will skip the call to err.write if there was no error 97 //to report. If there is an error, well, the program will still explode, 98 //but the user should see the error prior to the call that will make the 99 //program explode. 100 101 string temp = toString(sfErr_getOutput()); 102 if(temp.length > 0) 103 { 104 err.write(temp); 105 } 106 } 107 108 long getSampleCount() 109 { 110 return sfSoundFile_getSampleCount(m_soundFile); 111 } 112 uint getSampleRate() 113 { 114 return sfSoundFile_getSampleRate(m_soundFile); 115 } 116 uint getChannelCount() 117 { 118 return sfSoundFile_getChannelCount(m_soundFile); 119 } 120 121 122 123 124 } 125 126 private 127 { 128 129 extern(C++) interface soundInputStream 130 { 131 long read(void* data, long size); 132 133 long seek(long position); 134 135 long tell(); 136 137 long getSize(); 138 } 139 140 141 class soundFileStream:soundInputStream 142 { 143 private InputStream myStream; 144 145 this(InputStream stream) 146 { 147 myStream = stream; 148 } 149 150 extern(C++)long read(void* data, long size) 151 { 152 return myStream.read(data[0..cast(size_t)size]); 153 } 154 155 extern(C++)long seek(long position) 156 { 157 return myStream.seek(position); 158 } 159 160 extern(C++)long tell() 161 { 162 return myStream.tell(); 163 } 164 165 extern(C++)long getSize() 166 { 167 return myStream.getSize(); 168 } 169 } 170 171 172 extern(C) const(char)* sfErr_getOutput(); 173 174 175 extern(C) 176 { 177 178 struct sfSoundFile; 179 180 sfSoundFile* sfSoundFile_create(); 181 182 void sfSoundFile_destroy(sfSoundFile* file); 183 184 long sfSoundFile_getSampleCount(const sfSoundFile* file); 185 186 uint sfSoundFile_getChannelCount( const sfSoundFile* file); 187 188 uint sfSoundFile_getSampleRate(const sfSoundFile* file); 189 190 bool sfSoundFile_openReadFromFile(sfSoundFile* file, const char* filename); 191 192 bool sfSoundFile_openReadFromMemory(sfSoundFile* file,const(void)* data, long sizeInBytes); 193 194 bool sfSoundFile_openReadFromStream(sfSoundFile* file, soundInputStream stream); 195 196 //bool sfSoundFile_openReadFromStream(sfSoundFile* file, void* stream); 197 198 bool sfSoundFile_openWrite(sfSoundFile* file, const(char)* filename,uint channelCount,uint sampleRate); 199 200 long sfSoundFile_read(sfSoundFile* file, short* data, long sampleCount); 201 202 void sfSoundFile_write(sfSoundFile* file, const short* data, long sampleCount); 203 204 void sfSoundFile_seek(sfSoundFile* file, long timeOffset); 205 } 206 }