// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "AudioEncoder.h" #include "Engine/Audio/Config.h" #if COMPILE_WITH_AUDIO_TOOL && COMPILE_WITH_OGG_VORBIS #include /// /// Raw PCM data encoder to Ogg Vorbis audio format. /// /// class OggVorbisEncoder : public AudioEncoder { public: typedef void (*WriteCallback)(byte*, uint32, void*); private: static const uint32 BUFFER_SIZE = 4096; WriteCallback _writeCallback; void* _userData; byte _buffer[BUFFER_SIZE]; uint32 _bufferOffset; uint32 _numChannels; uint32 _bitDepth; bool _closed; ogg_stream_state _oggState; vorbis_info _vorbisInfo; vorbis_dsp_state _vorbisState; vorbis_block _vorbisBlock; public: /// /// Initializes a new instance of the class. /// OggVorbisEncoder(); /// /// Finalizes an instance of the class. /// ~OggVorbisEncoder(); public: /// /// Sets up the writer. Should be called before calling Write(). /// /// Callback that will be triggered when the writer is ready to output some data. The callback should copy the provided data into its own buffer. /// Determines how many samples per second the written data will have. /// Determines the size of a single sample, in bits. /// Determines the number of audio channels. Channel data will be output interleaved in the output buffer. /// The output data compression quality (normalized in range [0;1]). /// The custom used data passed to the write callback. /// True if failed to open the data, otherwise false. bool Open(WriteCallback writeCallback, uint32 sampleRate, uint32 bitDepth, uint32 numChannels, float quality, void* userData = nullptr); /// /// Writes a new set of samples and converts them to Ogg Vorbis. /// /// The samples in PCM format. 8-bit samples should be unsigned, but higher bit depths signed. Each sample is assumed to be the bit depth that was provided to the Open() method. /// The number of samples to encode. void Write(byte* samples, uint32 numSamples); /// /// Flushes the last of the data into the write buffer (triggers the write callback). This is called automatically when the writer is closed or goes out of scope. /// void Flush(); /// /// Closes the encoder and flushes the last of the data into the write buffer (triggers the write callback). This is called automatically when the writer goes out of scope. /// void Close(); private: /// /// Writes Vorbis blocks into Ogg packets. /// void WriteBlocks(); public: // [AudioEncoder] bool Convert(byte* samples, AudioDataInfo& info, BytesContainer& result, float quality = 0.5f) override; }; #endif