1 /** 2 Copyright (c) 2018 Clipsey (clipseypone@gmail.com) 3 4 Permission is hereby granted, free of charge, to any person or organization 5 obtaining a copy of the software and accompanying documentation covered by 6 this license (the "Software") to use, reproduce, display, distribute, 7 execute, and transmit the Software, and to prepare derivative works of the 8 Software, and to permit third-parties to whom the Software is furnished to 9 do so, all subject to the following: 10 11 The copyright notices in the Software and this entire statement, including 12 the above license grant, this restriction and the following disclaimer, 13 must be included in all copies of the Software, in whole or in part, and 14 all derivative works of the Software, unless such copies or derivative 15 works are solely in the form of machine-executable object code generated by 16 a source language processor. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 DEALINGS IN THE SOFTWARE. 25 */ 26 module ppc.types.audio; 27 import ppc.backend.loaders.audio.ogg; 28 import ppc.backend.loaders.audio.wav; 29 import ppc.backend.loaders.audio.pcm; 30 import ppc.backend.loaders.audio; 31 import ppc.backend; 32 import ppc.backend.signatures; 33 import ppc.backend.cfile; 34 35 public { 36 37 /// The type of audio 38 enum AudioType : ubyte { 39 OGG, 40 WAV, 41 PCM 42 } 43 44 /// Information about the audio 45 /// this struct is tightly packed (no padding) 46 struct AudioInfo { 47 align(1): 48 /// The type of audio format used. 49 AudioType type; 50 51 /// Version of audio format 52 ubyte version_; 53 54 /// The amount of channels 55 ubyte channels; 56 57 /// Bitrate of the audio stream 58 size_t bitrate; 59 60 /// Length of stream in samples 61 size_t pcmLength; 62 63 /// Length of stream in bytes 64 size_t rawLength; 65 } 66 67 /// returns true if the type is a valid audio type. 68 enum IsValidAudio(T) = (is(T : Ogg)); 69 70 /// A generic audio stream that can be read by OpenAL 71 struct Audio { 72 public: 73 /// Information about the audio file 74 AudioInfo info; 75 76 private: 77 AudioStream audioFile; 78 MemFile* mref; 79 80 public: 81 /// Creates Audio from memory 82 this(MemFile file) { 83 // Detect the right file format to use. 84 if (file.hasSignature(FileSignature.AudioOGG)) { 85 audioFile = new Ogg(file); 86 info = audioFile.genericInfo; 87 } 88 89 // Keep a reference to the file in memory so that the GC doesn't collect it by accident. 90 this.mref = &file; 91 } 92 93 /// Creates audio from file 94 this(string file) { 95 MemFile f = loadFile(file); 96 this(f); 97 } 98 99 /** 100 Read [bufferLength] bytes from stream to [ptr] 101 */ 102 ulong read(byte* ptr, size_t bufferLength = 4096) { 103 if (audioFile is null) return 0; 104 return audioFile.read(ptr, cast(uint)bufferLength); 105 } 106 107 byte[] readAll(uint bitdepth = SAMPLE_DEPTH_16BIT, bool signed = SAMPLE_SIGNED) { 108 import std.stdio; 109 byte[] buff = new byte[4096]; 110 byte[] bytes; 111 size_t bread = cast(size_t)this.read(buff.ptr); 112 while (bread != 0) { 113 bread = cast(size_t)this.read(buff.ptr); 114 bytes ~= buff[0..bread]; 115 } 116 return bytes; 117 } 118 119 /** 120 Seek to a byte in the stream 121 */ 122 void seek(long position = 0) { 123 audioFile.seekRaw(position); 124 } 125 126 /** 127 Seek to a sample in the stream 128 */ 129 void seekSample(long position = 0) { 130 audioFile.seek(position); 131 } 132 133 /// Returns the position in the stream 134 size_t tell() { 135 return audioFile.tell(); 136 } 137 } 138 }