diff --git a/dub.sdl b/dub.sdl index 6cd1346..841efdb 100644 --- a/dub.sdl +++ b/dub.sdl @@ -8,14 +8,14 @@ dependency "bindbc-opengl" version="~>0.13.0" dependency "bindbc-openal" version="~>0.4.1" dependency "imagefmt" version="~>2.1.0" dependency "dcontain" version="~>1.0.3" +dependency "bindbc-lua" version="~>0.4.1" dependency "bindbc-freetype" version="~>0.9.1" +dependency "audio-formats" version="~>1.3.7" dependency "sharpevents" version="~>2.0.0" dependency "bindbc-sdl" version="~>0.19.2" dependency "asdf" version="~>0.7.5" targetPath "out/" -libs "vorbisfile" "ogg" "vorbis" -sourceFiles "libs/ogg.lib" "libs/vorbisfile.lib" "libs/vorbis.lib" platform="windows" -copyFiles "libs/COPYING-FreeType" "libs/COPYING-XIPH" "libs/COPYING-OpenALSoft" "libs/README-SDL.txt" "res/fonts/LICENSE-KosugiMaru.txt" "res/fonts/LICENSE-PixelMPlus10.txt" -copyFiles "libs/libvorbis.dll" "libs/libvorbisfile.dll" "libs/freetype.dll" "libs/OpenAL32.dll" "libs/SDL2.dll" platform="windows" -versions "GL_42" "GL_AllowDeprecated" "SDL_2012" +copyFiles "libs/COPYING-FreeType" "libs/COPYING-OpenALSoft" "libs/README-SDL.txt" "res/fonts/LICENSE-KosugiMaru.txt" "res/fonts/LICENSE-PixelMPlus10.txt" +copyFiles "libs/OpenAL32.dll" "libs/SDL2.dll" platform="windows" +versions "GL_42" "GL_AllowDeprecated" "SDL_2012" "LUA_53" stringImportPaths "res/" diff --git a/libs/COPYING-XIPH b/libs/COPYING-XIPH deleted file mode 100644 index 6f67368..0000000 --- a/libs/COPYING-XIPH +++ /dev/null @@ -1,34 +0,0 @@ -This project uses libraries from the Xiph.org foundation. -The following libraries are used: - * libogg - * libvorbis - * libvorbisfile - -Copyright (c) 2002-2020 Xiph.org Foundation - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libs/libvorbis.dll b/libs/libvorbis.dll deleted file mode 100644 index b7aa11a..0000000 Binary files a/libs/libvorbis.dll and /dev/null differ diff --git a/libs/libvorbisfile.dll b/libs/libvorbisfile.dll deleted file mode 100644 index 12675a3..0000000 Binary files a/libs/libvorbisfile.dll and /dev/null differ diff --git a/libs/ogg.lib b/libs/ogg.lib deleted file mode 100644 index 4aa14f0..0000000 Binary files a/libs/ogg.lib and /dev/null differ diff --git a/libs/vorbis.lib b/libs/vorbis.lib deleted file mode 100644 index 198e7aa..0000000 Binary files a/libs/vorbis.lib and /dev/null differ diff --git a/libs/vorbisfile.lib b/libs/vorbisfile.lib deleted file mode 100644 index 2a0a858..0000000 Binary files a/libs/vorbisfile.lib and /dev/null differ diff --git a/source/engine/audio/astream/ogg.d b/source/engine/audio/astream/ogg.d deleted file mode 100644 index 3564fb7..0000000 --- a/source/engine/audio/astream/ogg.d +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright © 2020, Luna Nielsen - Distributed under the 2-Clause BSD License, see LICENSE file. - - Authors: Luna Nielsen -*/ -module engine.audio.astream.ogg; -import engine.audio.astream; -import vorbisfile; -import std.string; -import engine.core.log; -import std.exception; -import std.typecons; - -/** - An Ogg Vorbis audio stream -*/ -class OggStream : AudioStream { -private: - string fname; - OggVorbis_File file; - int section; - int word; - int signed; - - int bitrate_; - - - void verifyError(int error) { - switch(error) { - case OV_EREAD: throw new Exception("A read from media returned an error"); - case OV_ENOTVORBIS: throw new Exception("File is not a valid ogg vorbis file"); - case OV_EVERSION: throw new Exception("Vorbis version mismatch"); - case OV_EBADHEADER: throw new Exception("Bad OGG Vorbis header"); - case OV_EFAULT: throw new Exception("OGG Vorbis bug or stack corruption"); - default: break; - } - } - -public: - - /** - Deallocates on deconstruction - */ - ~this() { - ov_clear(&file); - } - - /** - Opens the OGG Vorbis stream file - */ - this(string file, bool bit16) { - this.fname = file; - - // Open the file and verify it opened correctly - int error = ov_fopen(file.toStringz, &this.file); - this.verifyError(error); - - // Get info about file - auto info = ov_info(&this.file, -1); - enforce(info.channels <= 2, "Too many channels in OGG Vorbis file"); - - this.bitrate_ = info.rate; - - // Set info about this file - this.channels = info.channels; - if (this.channels == 1) { - this.format = bit16 ? Format.Mono16 : Format.Mono8; - } else { - this.format = bit16 ? Format.Stereo16 : Format.Stereo8; - } - word = format == Format.Stereo8 || format == Format.Mono8 ? 1 : 2; - signed = format == Format.Mono16 || format == Format.Stereo16 ? 1 : 0; - } - - ptrdiff_t iReadSamples(ref ubyte[] toArray, size_t readLength) { - - // Read a verify the success of the read - ptrdiff_t readAmount = cast(ptrdiff_t)ov_read(&file, cast(byte*)toArray.ptr, cast(int)readLength, 0, word, signed, §ion); - assert(readAmount >= 0, "An error occured trying to read from the ogg vorbis stream"); - return readAmount; - } - -override: - ptrdiff_t readSamples(ref ubyte[] toArray) { - ubyte[] tmpBuf = new ubyte[4096]; - ptrdiff_t buffOffset; - ptrdiff_t buffLength; - do { - buffLength = iReadSamples(tmpBuf, toArray.length-buffOffset); - toArray[buffOffset..buffOffset+buffLength] = tmpBuf[0..buffLength]; - buffOffset += buffLength; - } while(buffOffset < toArray.length && buffLength > 0); - return buffOffset; - } - - /** - Gets whether the file can be seeked - */ - bool canSeek() { - return cast(bool)ov_seekable(&file); - } - - /** - Seek to a PCM location in the stream - */ - void seek(size_t location) { - ov_pcm_seek(&file, location); - } - - /** - Get the position in the stream - */ - size_t tell() { - return ov_pcm_tell(&file); - } - - /** - Gets the bitrate - */ - size_t bitrate() { - return bitrate_; - } - - /** - Gets info about the OGG audio - - Only music usually uses this - */ - AudioInfo getInfo() { - - // Inline function to get the ogg comments as a D string array - string[] getOggInfo() { - string[] fields; - - // Iterate over every comment - foreach(i; 0..file.vc.comments) { - immutable(int) commentLength = file.vc.comment_lengths[i]; - string comment = cast(string)file.vc.user_comments[i][0..commentLength]; - fields ~= comment; - } - return fields; - } - - // Parse ogg info as a array of key and value - string[2] parseOggInfo(string info) { - auto idx = info.indexOf("="); - enforce(idx >= 0, "Invalid info"); - return [info[0..idx], info[idx+1..$]]; - } - - // Inline function to parse the ogg info - string[string] parseOggInfos() { - string[string] infos; - - string[] fields = getOggInfo(); - foreach(i, field; fields) { - try { - string[2] info = parseOggInfo(field); - infos[info[0]] = info[1]; - } catch (Exception ex) { - AppLog.warn("Ogg Subsystem", "Failed the parse comment field %s: %s! Got data %s", i, ex.msg, field); - } - } - - return infos; - } - - AudioInfo info; - string[string] kv = parseOggInfos(); - info.file = this.fname; - if ("ARTIST" in kv) info.artist = kv["ARTIST"]; - if ("TITLE" in kv) info.title = kv["TITLE"]; - if ("ALBUM" in kv) info.album = kv["ALBUM"]; - if ("PERFOMER" in kv) info.performer = kv["PERFOMER"]; - if ("DATE" in kv) info.date = kv["DATE"]; - return info; - } -} \ No newline at end of file diff --git a/source/engine/audio/astream/package.d b/source/engine/audio/astream/package.d index 44c8f43..e37655e 100644 --- a/source/engine/audio/astream/package.d +++ b/source/engine/audio/astream/package.d @@ -5,150 +5,104 @@ Authors: Luna Nielsen */ module engine.audio.astream; -import engine.audio.astream.ogg; +import af = audioformats; import std.path; import bindbc.openal; import std.format; import std.range; /** - Open an audio file -*/ -AudioStream open(string file, bool bit16 = true) { - switch(file.extension) { - case ".ogg": return new OggStream(file, bit16); - default: throw new Exception("Unsupported file type (%s)".format(file.extension)); - } -} - - -/** - Information about audio, usually music + A stream of audio */ -struct AudioInfo { - - /** - The file of the audio - */ - string file; - - /** - The title of the audio - */ - string title; - - /** - The artist behind the music - */ - string artist; - - /** - The person performing the music - */ - string performer; +class AudioStream { +private: + // Backend stream + af.AudioStream* bStream; +public: /** - The person performing the music - */ - string album; + Reads all samples for a file + */ + float[] readAllSamples() { + float[] readBuffer; + float[4096] tempBuff; + while(true) { + int read = bStream.readSamplesFloat(tempBuff.ptr, tempBuff.length/2); + readBuffer ~= tempBuff[0..read*channels()]; + if (read <= 0) break; + } + return readBuffer; + } /** - Date of release, usually year + Opens an audio stream from memory */ - string date; + this(ubyte[] memory) { + bStream = new af.AudioStream; + bStream.openFromMemory(memory); + } /** - Get the audio info as a string - - According to Danish law even things CC0 or public domain has to include crediting - In the case the music doesn't (eg. the player drags music in to the game's music folder that is pirated) - We'll leave a little message for them :) + Opens an audio stream from file */ - string toString() { - if (artist.empty || title.empty) return "%s\n[Info missing! yarr harr?]".format(file); - - string base = "%s - %s".format(artist, title); - if (!album.empty) base ~= " from %s".format(album); - if (!date.empty) base ~= " (%s)".format(date); - if (!performer.empty) base ~= "\nPerfomed by %s".format(performer); - return base; + this(string file) { + bStream = new af.AudioStream; + bStream.openFromFile(file); } -} - -/** - Audio format of a stream -*/ -enum Format { - Mono8 = AL_FORMAT_MONO8, - Mono16 = AL_FORMAT_MONO16, - Stereo8 = AL_FORMAT_STEREO8, - Stereo16 = AL_FORMAT_STEREO16 -} -/** - A stream of audio -*/ -abstract class AudioStream { -public: /** The amount of channels in the audio stream */ - int channels; + int channels() { return bStream.getNumChannels(); } /** - Audio format of the stream - */ - Format format; + Read samples from the audio stream in to the array - /** - Read all samples from the stream till the end + Returns the amount of samples read + Returns 0 if there's no more samples */ - final ubyte[] readAll() { - ubyte[] data = new ubyte[4096]; - ubyte[] outData; - ptrdiff_t readCount = 0; - do { - readCount = readSamples(data); - outData ~= data[0..readCount]; - } while(readCount > 0); - - if (canSeek) seek(0); - return outData; + ptrdiff_t readSamples(ref float[] toArray) { + return cast(int)bStream.readSamplesFloat(toArray.ptr, cast(int)(toArray.length/channels))*channels; } -abstract: /** Read samples from the audio stream in to the array Returns the amount of samples read Returns 0 if there's no more samples */ - ptrdiff_t readSamples(ref ubyte[] toArray); - - /** - Gets whether the file can be seeked - */ - bool canSeek(); + ptrdiff_t readSamples(float* toArray, int samples) { + return bStream.readSamplesFloat(toArray, cast(int)(samples/channels))*channels; + } /** Seek to a PCM location in the stream */ - void seek(size_t location); + void seek(size_t location) { + bStream.seekPosition(cast(int)location/channels); + } /** Get the position in the stream */ - size_t tell(); + size_t tell() { return 0; } /** - Gets the bitrate of the stream + Gets the OpenAL format of the audio stream */ - size_t bitrate(); + ALenum format() { + return channels == 1 ? AL_FORMAT_MONO_FLOAT32 : AL_FORMAT_STEREO_FLOAT32; + } /** - Try to get the information about the audio + Returns the file format of the stream + */ + string fileFormat() { + return af.convertAudioFileFormatToString(bStream.getFormat()); + } - This information is usually only used for music + /** + Gets the sample rate of the stream */ - AudioInfo getInfo(); + int samplerate() { return cast(int)bStream.getSamplerate(); } } \ No newline at end of file diff --git a/source/engine/audio/music.d b/source/engine/audio/music.d index 8059732..41db420 100644 --- a/source/engine/audio/music.d +++ b/source/engine/audio/music.d @@ -31,7 +31,7 @@ void kmStopAllMusic() { */ class Music { private: - enum MUSIC_BUFF_SIZE = 4096; + enum MUSIC_BUFF_SIZE = 4096*4; enum MUSIC_BUFF_COUNT = 4; long lastReadLength; @@ -48,7 +48,7 @@ private: // The processing buffer ALuint pBuf; - ubyte[] pBufData = new ubyte[MUSIC_BUFF_SIZE*MUSIC_BUFF_COUNT]; + float[] pBufData = new float[MUSIC_BUFF_SIZE]; ALint state; // The buffer chain @@ -58,7 +58,7 @@ private: // Fill buffers with initial data foreach(i; 0..MUSIC_BUFF_COUNT) { lastReadLength = stream.readSamples(pBufData); - alBufferData(buffers[i], stream.format, pBufData.ptr, cast(int)lastReadLength, cast(int)stream.bitrate); + alBufferData(buffers[i], stream.format, pBufData.ptr, cast(int)(lastReadLength*float.sizeof), stream.samplerate); alSourceQueueBuffers(sourceId, 1, &buffers[i]); } @@ -78,9 +78,9 @@ private: // Read samples to buffer lastReadLength = stream.readSamples(pBufData); - if (lastReadLength == 0) { + if (lastReadLength <= 0) { // If we're at the end and we should loop then loop. (if possible) - if (looping && stream.canSeek) { + if (looping) { // Seek back to start of stream and read samples stream.seek(0); @@ -94,7 +94,7 @@ private: } // Buffer the data to OpenAL - alBufferData(pBuf, stream.format, pBufData.ptr, cast(int)lastReadLength, cast(int)stream.bitrate); + alBufferData(pBuf, stream.format, pBufData.ptr, cast(int)(lastReadLength*float.sizeof), stream.samplerate); // Re-queue buffer alSourceQueueBuffers(sourceId, 1, &pBuf); @@ -142,7 +142,14 @@ public: Construct a sound from a file path */ this(string file, string channel = null) { - this(open(file), channel); + this(new AudioStream(file), channel); + } + + /** + Construct a sound from a file path + */ + this(ubyte[] data, string channel = null) { + this(new AudioStream(data), channel); } /** @@ -240,9 +247,9 @@ public: } /** - Get info about the music + File format of the audio stream used */ - AudioInfo getInfo() { - return stream.getInfo(); + string fileFormat() { + return stream.fileFormat; } } \ No newline at end of file diff --git a/source/engine/audio/sound.d b/source/engine/audio/sound.d index ca5e988..b9a274c 100644 --- a/source/engine/audio/sound.d +++ b/source/engine/audio/sound.d @@ -15,6 +15,10 @@ import engine.math; */ class Sound { private: + float[] buffer; + string fFormat; + int channels; + ALuint bufferId; ALuint sourceId; @@ -30,7 +34,14 @@ public: Construct a sound from a file path */ this(string file, string channel=null) { - this(open(file), channel); + this(new AudioStream(file), channel); + } + + /** + Construct a sound from a file path + */ + this(ubyte[] data, string channel=null) { + this(new AudioStream(data), channel); } /** @@ -40,8 +51,12 @@ public: // Generate buffer alGenBuffers(1, &bufferId); - ubyte[] data = stream.readAll(); - alBufferData(bufferId, stream.format, data.ptr, cast(int)data.length, cast(int)stream.bitrate/stream.channels); + buffer = stream.readAllSamples(); + alBufferData(bufferId, stream.format, buffer.ptr, cast(int)buffer.length*4, stream.samplerate); + + // Set info + fFormat = stream.fileFormat; + channels = stream.channels; // Generate source alGenSources(1, &sourceId); @@ -89,4 +104,11 @@ public: void stop() { alSourceStop(sourceId); } + + /** + Returns the file format of the audio source + */ + string fileFormat() { + return fFormat; + } } \ No newline at end of file diff --git a/source/engine/package.d b/source/engine/package.d index 4a2b8f0..94f073a 100644 --- a/source/engine/package.d +++ b/source/engine/package.d @@ -14,6 +14,7 @@ public import engine.net; public import engine.ui; public import engine.game; public import engine.i18n; +public import engine.scripting; import bindbc.sdl; import bindbc.openal; @@ -61,6 +62,7 @@ void initEngine() { // Initialize subsystems AppLog.info("Engine", "Intialized internal state for renderer..."); + initScripting(); } /** diff --git a/source/vorbisfile.d b/source/vorbisfile.d deleted file mode 100644 index 7accec2..0000000 --- a/source/vorbisfile.d +++ /dev/null @@ -1,240 +0,0 @@ -/* - Copyright © 2020, Luna Nielsen - Distributed under the 2-Clause BSD License, see LICENSE file. - - Authors: Luna Nielsen -*/ -module vorbisfile; -import core.stdc.config; - -alias ogg_int64_t = long; -alias ogg_uint64_t = ulong; -alias ogg_int32_t = int; -alias ogg_uint32_t = uint; -alias ogg_int16_t = short; -alias ogg_uint16_t = ushort; - -struct vorbis_info { - int _version; // Renamed from "version", since that's a keyword in D - int channels; - int rate; - c_long bitrate_upper; - c_long bitrate_nominal; - c_long bitrate_lower; - c_long bitrate_window; - - void *codec_setup; -} - -struct vorbis_dsp_state { - int analysisp; - vorbis_info* vi; - float** pcm; - float** pcmret; - int pcm_storage; - int pcm_current; - int pcm_returned; - int preextrapolate; - int eofflag; - c_long lW; - c_long W; - c_long nW; - c_long centerW; - ogg_int64_t granulepos; - ogg_int64_t sequence; - ogg_int64_t glue_bits; - ogg_int64_t time_bits; - ogg_int64_t floor_bits; - ogg_int64_t res_bits; - void* backend_state; -} - -struct vorbis_comment { - char** user_comments; - int* comment_lengths; - int comments; - char* vendor; -} - -struct alloc_chain { - void* ptr; - alloc_chain* next; -} - -struct vorbis_block { - float** pcm; - oggpack_buffer opb; - c_long lW; - c_long W; - c_long nW; - int pcmend; - int mode; - int eofflag; - ogg_int64_t granulepos; - ogg_int64_t sequence; - vorbis_dsp_state* vd; - void* localstore; - c_long localtop; - c_long localalloc; - c_long totaluse; - alloc_chain* reap; - c_long glue_bits; - c_long time_bits; - c_long floor_bits; - c_long res_bits; - void* internal; -} - - -struct ogg_iovec_t { - void* iov_base; - size_t iov_len; -} - -struct oggpack_buffer { - c_long endbyte; - int endbit; - ubyte* buffer; - ubyte* ptr; - c_long storage; -} - -struct ogg_page { - ubyte* header; - c_long header_len; - ubyte* _body; // originally named "body", but that's a keyword in D. - c_long body_len; -} - -struct ogg_stream_state { - ubyte* body_data; - c_long body_storage; - c_long body_fill; - c_long body_returned; - int* lacing_vals; - ogg_int64_t* granule_vals; - c_long lacing_storage; - c_long lacing_fill; - c_long lacing_packet; - c_long lacing_returned; - ubyte[282] header; - int header_fill; - int e_o_s; - int b_o_s; - c_long serialno; - c_long pageno; - ogg_int64_t packetno; - ogg_int64_t granulepos; -} - -struct ogg_packet { - ubyte* packet; - c_long bytes; - c_long b_o_s; - c_long e_o_s; - ogg_int64_t granulepos; - ogg_int64_t packetno; -} - -struct ogg_sync_state { - ubyte* data; - int storage; - int fill; - int returned; - - int unsynced; - int headerbytes; - int bodybytes; -} - -struct ov_callbacks { - extern(C) nothrow { - size_t function(void*, size_t, size_t, void*) read_func; - int function(void*, ogg_int64_t, int) seek_func; - int function(void*) close_func; - c_long function(void*) tell_func; - } -} - -enum { - NOTOPEN =0, - PARTOPEN =1, - OPENED =2, - STREAMSET =3, - INITSET =4, - - OV_FALSE = -1, - OV_EOF = -2, - OV_HOLE = -3, - OV_EREAD = -128, - OV_EFAULT = -129, - OV_EIMPL = -130, - OV_EINVAL = -131, - OV_ENOTVORBIS = -132, - OV_EBADHEADER = -133, - OV_EVERSION = -134, - OV_ENOTAUDIO = -135, - OV_EBADPACKET = -136, - OV_EBADLINK = -137, - OV_ENOSEEK = -138, -} - -struct OggVorbis_File { - void* datasource; - int seekable; - ogg_int64_t offset; - ogg_int64_t end; - ogg_sync_state oy; - int links; - ogg_int64_t* offsets; - ogg_int64_t* dataoffsets; - c_long* serialnos; - ogg_int64_t* pcmlengths; - vorbis_info* vi; - vorbis_comment* vc; - ogg_int64_t pcm_offset; - int ready_state; - c_long current_serialno; - int current_link; - double bittrack; - double samptrack; - ogg_stream_state os; - vorbis_dsp_state vd; - vorbis_block vb; - ov_callbacks callbacks; -} - -extern(C) @nogc nothrow __gshared: -int ov_clear(OggVorbis_File*); -int ov_fopen(const(char)*, OggVorbis_File*); -int ov_open_callbacks(void* datasource, OggVorbis_File*, const(char)*, c_long, ov_callbacks); -int ov_test_callbacks(void*, OggVorbis_File*, const(char)*, c_long, ov_callbacks); -int ov_test_open(OggVorbis_File*); -c_long ov_bitrate(OggVorbis_File*, int); -c_long ov_bitrate_instant(OggVorbis_File*); -c_long ov_streams(OggVorbis_File*); -c_long ov_seekable(OggVorbis_File*); -c_long ov_serialnumber(OggVorbis_File*, int); -ogg_int64_t ov_raw_total(OggVorbis_File*, int); -ogg_int64_t ov_pcm_total(OggVorbis_File*, int); -double ov_time_total(OggVorbis_File*, int); -int ov_raw_seek(OggVorbis_File*, ogg_int64_t); -int ov_pcm_seek(OggVorbis_File*, ogg_int64_t); -int ov_pcm_seek_page(OggVorbis_File*, ogg_int64_t); -int ov_time_seek(OggVorbis_File*, double); -int ov_time_seek_page(OggVorbis_File*, double); -int ov_raw_seek_lap(OggVorbis_File*, ogg_int64_t); -int ov_pcm_seek_lap(OggVorbis_File*, ogg_int64_t); -int ov_pcm_seek_page_lap(OggVorbis_File*, ogg_int64_t); -int ov_time_seek_lap(OggVorbis_File*, double); -int ov_time_seek_page_lap(OggVorbis_File*, double); -ogg_int64_t ov_raw_tell(OggVorbis_File*); -ogg_int64_t ov_pcm_tell(OggVorbis_File*); -double ov_time_tell(OggVorbis_File*); -vorbis_info* ov_info(OggVorbis_File*, int); -vorbis_comment* ov_comment(OggVorbis_File*, int); -c_long ov_read_float(OggVorbis_File*, float***, int, int*); -c_long ov_read(OggVorbis_File*, byte*, int, int, int, int, int*); -int ov_crosslap(OggVorbis_File*, OggVorbis_File*); -int ov_halfrate(OggVorbis_File*, int); -int ov_halfrate_p(OggVorbis_File*); \ No newline at end of file