1 /*
2 *******************************************************************************************
3 * Dgame (a D game framework) - Copyright (c) Randy Schütt
4 * 
5 * This software is provided 'as-is', without any express or implied warranty.
6 * In no event will the authors be held liable for any damages arising from
7 * the use of this software.
8 * 
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 * 
13 * 1. The origin of this software must not be misrepresented; you must not claim
14 *    that you wrote the original software. If you use this software in a product,
15 *    an acknowledgment in the product documentation would be appreciated but is
16 *    not required.
17 * 
18 * 2. Altered source versions must be plainly marked as such, and must not be
19 *    misrepresented as being the original software.
20 * 
21 * 3. This notice may not be removed or altered from any source distribution.
22 *******************************************************************************************
23 */
24 module Dgame.Audio.SoundFile;
25 
26 private {
27 	import std.file : exists;
28 
29 	import Dgame.Internal.Log;
30 }
31 
32 package import core.stdc.stdio : FILE, fopen, fseek, fread, fclose, SEEK_SET;
33 
34 /**
35  * A helper struct for reading from a sound file.
36  */
37 
38 struct SoundFile {
39 	uint rate;			/** The sound rate */
40 	uint dataSize;		/** Total data size */
41 	ushort channels;		/** Number of channels */
42 	ushort bits;			/** Number of bits */
43 	ushort bytes;		/** Number of bytes */
44 }
45 
46 /**
47  * All supported music types.
48  */
49 enum MusicType : ubyte {
50 	None,	/** For invalid types */
51 	Wave,	/** Wave files */
52 	Mod,	/** Mod  -> TODO */
53 	Midi,	/** Midi -> TODO */
54 	Ogg,	/** Ogg or vorbis files. */
55 	Mp3		/** Mp3  -> TODO */
56 }
57 
58 /**
59  * The abstract basic class for sound file loading.
60  *
61  * Author: rschuett
62  */
63 abstract class BaseSoundFile {
64 protected:
65 	SoundFile _sFile = void;
66 
67 	string _filename;
68 	byte[] _buffer;
69 	
70 	abstract void _read(string filename);
71 	
72 public:
73 //final:
74 	/**
75 	 * CTor
76 	 */
77 	this(string filename) {
78 		if (!exists(filename))
79 			Log.error("File " ~ filename ~ " does not exists.");
80 		
81 		this._read(filename);
82 	}
83 
84 	/**
85 	 * Returns the SoundFile struct.
86 	 *
87 	 * See: SoundFile struct
88 	 */
89 	final ref const(SoundFile) getData() const pure nothrow {
90 		return this._sFile;
91 	}
92 
93 	/**
94 	 * Returns the Sound Buffer
95 	 */
96 	final const(byte[]) getBuffer() const pure nothrow {
97 		return this._buffer;
98 	}
99 	
100 	/**
101 	 * Returns the filename of the loaded sound file.
102 	 */
103 	final string getFilename() const pure nothrow {
104 		return this._filename;
105 	}
106 	
107 	/**
108 	 * Returns the length of the sound in seconds.
109 	 */
110 	float getLength() const pure nothrow {
111 		return (0f + 8 * this._sFile.dataSize) / (this._sFile.bits * this._sFile.rate * this._sFile.channels);
112 	}
113 
114 //virtual:
115 	/**
116 	 * abstract getType method.
117 	 */
118 	abstract MusicType getType() const pure nothrow;
119 	
120 	/**
121 	 * toString
122 	 */
123 	override string toString() const pure nothrow {
124 		return this.getFilename();
125 	}
126 }