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 }