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 | |
8 | namespace 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 | |