1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "vorbis/vorbisenc.h"
7
8namespace bs
9{
10 /** @addtogroup OpenAudio
11 * @{
12 */
13
14 /** Used for encoding PCM to Ogg Vorbis audio data. */
15 class OggVorbisEncoder
16 {
17 public:
18 OggVorbisEncoder() = default;
19 ~OggVorbisEncoder();
20
21 /**
22 * Sets up the writer. Should be called before calling write().
23 *
24 * @param[in] writeCallback Callback that will be triggered when the writer is ready to output some data.
25 * The callback should copy the provided data into its own buffer.
26 * @param[in] sampleRate Determines how many samples per second the written data will have.
27 * @param[in] bitDepth Determines the size of a single sample, in bits.
28 * @param[in] numChannels Determines the number of audio channels. Channel data will be output interleaved
29 * in the output buffer.
30 */
31 bool open(std::function<void(UINT8*, UINT32)> writeCallback, UINT32 sampleRate, UINT32 bitDepth, UINT32 numChannels);
32
33 /**
34 * Writes a new set of samples and converts them to Ogg Vorbis.
35 *
36 * @param[in] samples Samples in PCM format. 8-bit samples should be unsigned, but higher bit depths signed.
37 * Each sample is assumed to be the bit depth that was provided to the open() method.
38 * @param[in] numSamples Number of samples to encode.
39 */
40 void write(UINT8* samples, UINT32 numSamples);
41
42 /**
43 * Flushes the last of the data into the write buffer (triggers the write callback). This is called automatically
44 * when the writer is closed or goes out of scope.
45 */
46 void flush();
47
48 /**
49 * Closes the encoder and flushes the last of the data into the write buffer (triggers the write callback). This is
50 * called automatically when the writer goes out of scope.
51 */
52 void close();
53
54 /**
55 * Helper method that allows you to quickly convert PCM to Ogg Vorbis data.
56 *
57 * @param[in] samples Buffer containing samples in PCM format. All samples should be in signed integer format.
58 * @param[in] info Meta-data describing the provided samples.
59 * @param[out] size Number of bytes written to the output buffer.
60 * @return Buffer containing the encoded samples, allocated using the general allocator.
61 */
62 static UINT8* PCMToOggVorbis(UINT8* samples, const AudioDataInfo& info, UINT32& size);
63 private:
64 /** Writes Vorbis blocks into Ogg packets. */
65 void writeBlocks();
66
67 static const UINT32 BUFFER_SIZE = 4096;
68
69 std::function<void(UINT8*, UINT32)> mWriteCallback;
70 UINT8 mBuffer[BUFFER_SIZE];
71 UINT32 mBufferOffset = 0;
72 UINT32 mNumChannels = 0;
73 UINT32 mBitDepth = 0;
74 bool mClosed = true;
75
76 ogg_stream_state mOggState;
77 vorbis_info mVorbisInfo;
78 vorbis_dsp_state mVorbisState;
79 vorbis_block mVorbisBlock;
80 };
81
82 /** @} */
83}
84