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.VorbisFile; 25 26 private { 27 import std..string : toStringz; 28 29 import derelict.ogg.ogg; 30 import derelict.vorbis.vorbis; 31 import derelict.vorbis.file; 32 //import derelict.vorbis.enc; 33 34 import Dgame.Internal.Log; 35 import Dgame.Internal.Unique; 36 import Dgame.Audio.SoundFile; 37 } 38 39 /** 40 * An alias for VorbisFile 41 */ 42 alias OggFile = VorbisFile; 43 44 /** 45 * An Ogg/Vorbis implementation of BaseSoundFile 46 * Open an ogg/vorbis file and store the attributes from it's headers. 47 * 48 * Author: rschuett 49 */ 50 class VorbisFile : BaseSoundFile { 51 protected: 52 override void _read(string filename) { 53 super._filename = filename; 54 55 OggVorbis_File oggFile = void; 56 scope(exit) ov_clear(&oggFile); 57 58 if (ov_fopen(toStringz(filename), &oggFile) < 0) 59 Log.error(filename ~ " is no valid Vorbis file."); 60 61 // Get some information about the OGG file 62 vorbis_info* pInfo = ov_info(&oggFile, -1); 63 64 super._sFile.rate = pInfo.rate; 65 super._sFile.bits = 16; 66 super._sFile.bytes = 2; 67 super._sFile.dataSize = cast(uint) ov_pcm_total(&oggFile, -1) * super._sFile.bytes * pInfo.channels; 68 super._sFile.channels = cast(ubyte) pInfo.channels; 69 70 debug Log.info("Allocate %d memory for Vorbis file %s.", _sFile.dataSize, filename); 71 super._buffer = new byte[super._sFile.dataSize]; 72 73 unique_ptr!(byte) tmpBuf = allocate_unique!(byte)(ushort.max); 74 // byte[] tmpBuf = new byte[ushort.max]; 75 76 uint inserted = 0; 77 while (true) { 78 // Read up to a buffer's worth of decoded sound data 79 long bytes = ov_read(&oggFile, &tmpBuf[0], ushort.max, 0, 2, 1, null); 80 if (bytes <= 0) 81 break; 82 // Append to end of buffer 83 uint bytes_read = cast(uint) bytes; 84 85 super._buffer[inserted .. inserted + bytes_read] = tmpBuf[0 .. bytes_read]; 86 87 inserted += bytes; 88 } 89 } 90 91 public: 92 /** 93 * CTor 94 */ 95 this(string filename) { 96 super(filename); 97 } 98 99 /** 100 * Returns the music type. In this case: Ogg. 101 */ 102 override MusicType getType() const pure nothrow { 103 return MusicType.Ogg; 104 } 105 }