31#if JUCE_MAC && ! defined (__MACOSX__)
35namespace OggVorbisNamespace
37#if JUCE_INCLUDE_OGGVORBIS_CODE || ! defined (JUCE_INCLUDE_OGGVORBIS_CODE)
38 JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706 4995 4365 4456 4457 4459 6297 6011 6001 6308 6255 6386 6385 6246 6387 6263 6262 28182)
43 "-Wdeprecated-register",
44 "-Wdeprecated-declarations",
46 "-Wzero-as-null-pointer-constant",
50 "-Wmisleading-indentation",
51 "-Wmissing-prototypes",
53 "-Wmaybe-uninitialized")
56 #include "oggvorbis/vorbisenc.h"
98static const char*
const oggFormatName =
"Ogg-Vorbis file";
100const char*
const OggVorbisAudioFormat::encoderName =
"encoder";
101const char*
const OggVorbisAudioFormat::id3title =
"id3title";
102const char*
const OggVorbisAudioFormat::id3artist =
"id3artist";
103const char*
const OggVorbisAudioFormat::id3album =
"id3album";
104const char*
const OggVorbisAudioFormat::id3comment =
"id3comment";
105const char*
const OggVorbisAudioFormat::id3date =
"id3date";
106const char*
const OggVorbisAudioFormat::id3genre =
"id3genre";
107const char*
const OggVorbisAudioFormat::id3trackNumber =
"id3trackNumber";
111class OggReader :
public AudioFormatReader
114 OggReader (InputStream* inp) : AudioFormatReader (inp, oggFormatName)
117 usesFloatingPointData =
true;
119 callbacks.read_func = &oggReadCallback;
120 callbacks.seek_func = &oggSeekCallback;
121 callbacks.close_func = &oggCloseCallback;
122 callbacks.tell_func = &oggTellCallback;
131 addMetadataItem (comment,
"ENCODER", OggVorbisAudioFormat::encoderName);
132 addMetadataItem (comment,
"TITLE", OggVorbisAudioFormat::id3title);
133 addMetadataItem (comment,
"ARTIST", OggVorbisAudioFormat::id3artist);
134 addMetadataItem (comment,
"ALBUM", OggVorbisAudioFormat::id3album);
135 addMetadataItem (comment,
"COMMENT", OggVorbisAudioFormat::id3comment);
136 addMetadataItem (comment,
"DATE", OggVorbisAudioFormat::id3date);
137 addMetadataItem (comment,
"GENRE", OggVorbisAudioFormat::id3genre);
138 addMetadataItem (comment,
"TRACKNUMBER", OggVorbisAudioFormat::id3trackNumber);
141 numChannels = (
unsigned int)
info->channels;
143 sampleRate = (double)
info->rate;
145 reservoir.setSize ((
int) numChannels, (
int)
jmin (lengthInSamples, (
int64) 4096));
149 ~OggReader()
override
154 void addMetadataItem (OggVorbisNamespace::vorbis_comment* comment,
const char*
name,
const char* metadataName)
157 metadataValues.set (metadataName,
value);
161 bool readSamples (
int** destSamples,
int numDestChannels,
int startOffsetInDestBuffer,
162 int64 startSampleInFile,
int numSamples)
override
164 const auto getBufferedRange = [
this] {
return bufferedRange; };
166 const auto readFromReservoir = [
this, &destSamples, &numDestChannels, &startOffsetInDestBuffer, &startSampleInFile] (
const Range<int64> rangeToRead)
168 const auto bufferIndices = rangeToRead - bufferedRange.getStart();
169 const auto writePos = (
int64) startOffsetInDestBuffer + (rangeToRead.getStart() - startSampleInFile);
171 for (
int i =
jmin (numDestChannels, reservoir.getNumChannels()); --
i >= 0;)
172 if (destSamples[
i] !=
nullptr)
173 memcpy (destSamples[
i] + writePos,
174 reservoir.getReadPointer (
i) + bufferIndices.getStart(),
175 (
size_t) bufferIndices.getLength() * sizeof (
float));
178 const auto fillReservoir = [
this] (
int64 requestedStart)
180 const auto newStart =
jmax ((
int64) 0, requestedStart);
181 bufferedRange = Range<int64> { newStart, newStart + reservoir.getNumSamples() };
183 if (bufferedRange.getStart() !=
ov_pcm_tell (&ovFile))
188 int numToRead = (
int) bufferedRange.getLength();
190 while (numToRead > 0)
192 float** dataIn =
nullptr;
193 auto samps =
static_cast<int> (
ov_read_float (&ovFile, &dataIn, numToRead, &bitStream));
200 for (
int i =
jmin ((
int) numChannels, reservoir.getNumChannels()); --
i >= 0;)
201 memcpy (reservoir.getWritePointer (
i, offset), dataIn[
i], (
size_t) samps * sizeof (
float));
208 reservoir.clear (offset, numToRead);
211 const auto remainingSamples = Reservoir::doBufferedRead (Range<int64> { startSampleInFile, startSampleInFile + numSamples },
216 if (! remainingSamples.isEmpty())
217 for (
int i = numDestChannels; --
i >= 0;)
218 if (destSamples[
i] !=
nullptr)
219 zeromem (destSamples[
i] + startOffsetInDestBuffer, (
size_t) remainingSamples.getLength() * sizeof (
int));
225 static size_t oggReadCallback (
void* ptr,
size_t size,
size_t nmemb,
void* datasource)
227 return (
size_t) (
static_cast<InputStream*
> (datasource)->read (ptr, (
int) (
size * nmemb))) /
size;
230 static int oggSeekCallback (
void* datasource, OggVorbisNamespace::ogg_int64_t offset,
int whence)
232 auto*
in =
static_cast<InputStream*
> (datasource);
235 offset +=
in->getPosition();
237 offset +=
in->getTotalLength();
239 in->setPosition (offset);
243 static int oggCloseCallback (
void*)
248 static long oggTellCallback (
void* datasource)
250 return (
long)
static_cast<InputStream*
> (datasource)->getPosition();
254 OggVorbisNamespace::OggVorbis_File ovFile;
255 OggVorbisNamespace::ov_callbacks callbacks;
256 AudioBuffer<float> reservoir;
257 Range<int64> bufferedRange;
263class OggWriter :
public AudioFormatWriter
266 OggWriter (OutputStream*
out,
double rate,
267 unsigned int numChans,
unsigned int bitsPerSamp,
268 int qualityIndex,
const StringPairArray& metadata)
269 : AudioFormatWriter (
out, oggFormatName, rate, numChans, bitsPerSamp)
274 jlimit (0.0f, 1.0f, (
float) qualityIndex * 0.1f)) == 0)
278 addMetadata (metadata, OggVorbisAudioFormat::encoderName,
"ENCODER");
279 addMetadata (metadata, OggVorbisAudioFormat::id3title,
"TITLE");
280 addMetadata (metadata, OggVorbisAudioFormat::id3artist,
"ARTIST");
281 addMetadata (metadata, OggVorbisAudioFormat::id3album,
"ALBUM");
282 addMetadata (metadata, OggVorbisAudioFormat::id3comment,
"COMMENT");
283 addMetadata (metadata, OggVorbisAudioFormat::id3date,
"DATE");
284 addMetadata (metadata, OggVorbisAudioFormat::id3genre,
"GENRE");
285 addMetadata (metadata, OggVorbisAudioFormat::id3trackNumber,
"TRACKNUMBER");
292 OggVorbisNamespace::ogg_packet header, header_comm, header_code;
304 output->write (og.header, (
size_t) og.header_len);
305 output->write (og.body, (
size_t) og.body_len);
312 ~OggWriter()
override
336 bool write (
const int** samplesToWrite,
int numSamples)
override
342 const double gain = 1.0 / 0x80000000u;
345 for (
int i = (
int) numChannels; --
i >= 0;)
347 if (
auto* dst = vorbisBuffer[
i])
349 if (
const int* src = samplesToWrite [
i])
351 for (
int j = 0;
j < numSamples; ++
j)
352 dst[
j] = (
float) (src[
j] * gain);
358 writeSamples (numSamples);
364 void writeSamples (
int numSamples)
382 output->write (og.header, (
size_t) og.header_len);
383 output->write (og.body, (
size_t) og.body_len);
395 OggVorbisNamespace::ogg_stream_state
os;
396 OggVorbisNamespace::ogg_page og;
397 OggVorbisNamespace::ogg_packet op;
398 OggVorbisNamespace::vorbis_info vi;
399 OggVorbisNamespace::vorbis_comment vc;
400 OggVorbisNamespace::vorbis_dsp_state vd;
401 OggVorbisNamespace::vorbis_block vb;
403 void addMetadata (
const StringPairArray& metadata,
const char*
name,
const char* vorbisName)
405 auto s = metadata [
name];
416OggVorbisAudioFormat::OggVorbisAudioFormat() : AudioFormat (oggFormatName,
".ogg")
420OggVorbisAudioFormat::~OggVorbisAudioFormat()
424Array<int> OggVorbisAudioFormat::getPossibleSampleRates()
426 return { 8000, 11025, 12000, 16000, 22050, 32000,
427 44100, 48000, 88200, 96000, 176400, 192000 };
430Array<int> OggVorbisAudioFormat::getPossibleBitDepths()
435bool OggVorbisAudioFormat::canDoStereo() {
return true; }
436bool OggVorbisAudioFormat::canDoMono() {
return true; }
437bool OggVorbisAudioFormat::isCompressed() {
return true; }
439AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream*
in,
bool deleteStreamIfOpeningFails)
441 std::unique_ptr<OggReader>
r (
new OggReader (
in));
443 if (
r->sampleRate > 0)
446 if (! deleteStreamIfOpeningFails)
452AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream*
out,
454 unsigned int numChannels,
456 const StringPairArray& metadataValues,
457 int qualityOptionIndex)
462 std::unique_ptr<OggWriter>
w (
new OggWriter (
out, sampleRate, numChannels,
463 (
unsigned int) bitsPerSample,
464 qualityOptionIndex, metadataValues));
466 return w->ok ?
w.release() :
nullptr;
469StringArray OggVorbisAudioFormat::getQualityOptions()
471 return {
"64 kbps",
"80 kbps",
"96 kbps",
"112 kbps",
"128 kbps",
"160 kbps",
472 "192 kbps",
"224 kbps",
"256 kbps",
"320 kbps",
"500 kbps" };
475int OggVorbisAudioFormat::estimateOggFileQuality (
const File& source)
479 if (
auto r = std::unique_ptr<AudioFormatReader> (createReaderFor (
in.release(),
true)))
481 auto lengthSecs = (double)
r->lengthInSamples /
r->sampleRate;
482 auto approxBitsPerSecond = (
int) ((
double) source.
getSize() * 8 / lengthSecs);
484 auto qualities = getQualityOptions();
486 int bestDiff = 10000;
488 for (
int i = qualities.size(); --
i >= 0;)
490 auto diff = std::abs (qualities[
i].getIntValue() - approxBitsPerSecond);
Type jmin(const Type a, const Type b)
Definition MathsFunctions.h:60
Type jmax(const Type a, const Type b)
Definition MathsFunctions.h:48
int64_t int64
Definition basics.h:91
uint32_t uint32
Definition basics.h:90
FileInputStream * createInputStream() const
Definition File.cpp:733
int64 getSize() const
Definition File.cpp:1352
Definition StringArray.h:41
void vorbis_comment_init(vorbis_comment *vc)
Definition info.c:54
int vorbis_analysis_blockout(vorbis_dsp_state *v, vorbis_block *vb)
Definition block.c:523
void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents)
Definition info.c:70
char * vorbis_comment_query(vorbis_comment *vc, const char *tag, int count)
Definition info.c:92
void vorbis_comment_clear(vorbis_comment *vc)
Definition info.c:132
int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op)
Definition bitrate.c:229
int vorbis_analysis(vorbis_block *vb, ogg_packet *op)
Definition analysis.c:29
void vorbis_dsp_clear(vorbis_dsp_state *v)
Definition block.c:314
float ** vorbis_analysis_buffer(vorbis_dsp_state *v, int vals)
Definition block.c:388
int vorbis_block_clear(vorbis_block *vb)
Definition block.c:148
int vorbis_analysis_headerout(vorbis_dsp_state *v, vorbis_comment *vc, ogg_packet *op, ogg_packet *op_comm, ogg_packet *op_code)
Definition info.c:590
int vorbis_bitrate_addblock(vorbis_block *vb)
Definition bitrate.c:73
int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb)
Definition block.c:77
void vorbis_info_clear(vorbis_info *vi)
Definition info.c:159
int vorbis_analysis_init(vorbis_dsp_state *v, vorbis_info *vi)
Definition block.c:294
int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals)
Definition block.c:459
void vorbis_info_init(vorbis_info *vi)
Definition info.c:154
UINT_D64 w
Definition inflate.c:942
register unsigned j
Definition inflate.c:1576
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
int ogg_stream_clear(ogg_stream_state *os)
Definition framing.c:162
int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op)
Definition framing.c:339
int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og)
Definition framing.c:510
int ogg_stream_flush(ogg_stream_state *os, ogg_page *og)
Definition framing.c:494
int ogg_stream_init(ogg_stream_state *os, int serialno)
Definition framing.c:133
int ogg_page_eos(const ogg_page *og)
Definition framing.c:45
static PuglViewHint int value
Definition pugl.h:1708
static const char * name
Definition pugl.h:1582
struct backing_store_struct * info
Definition jmemsys.h:183
#define JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...)
Definition juce_CompilerWarnings.h:181
#define JUCE_END_IGNORE_WARNINGS_GCC_LIKE
Definition juce_CompilerWarnings.h:182
#define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)
Definition juce_CompilerWarnings.h:198
#define JUCE_END_NO_SANITIZE
Definition juce_CompilerWarnings.h:218
#define JUCE_END_IGNORE_WARNINGS_MSVC
Definition juce_CompilerWarnings.h:199
#define JUCE_BEGIN_NO_SANITIZE(warnings)
Definition juce_CompilerWarnings.h:217
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
Definition carla_juce.cpp:31
void zeromem(void *memory, size_t numBytes) noexcept
Definition juce_Memory.h:28
static bool diff(const std::string fn1, const std::string fn2)
Definition playertest.cpp:161
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
typedef int(UZ_EXP MsgFn)()
#define SEEK_CUR
Definition unzpriv.h:1303
#define SEEK_END
Definition unzpriv.h:1304
static ZCONST char Far * os[NUM_HOSTS]
Definition zipinfo.c:1001
int vorbis_encode_init_vbr(vorbis_info *vi, long channels, long rate, float base_quality)
Definition vorbisenc.c:927
vorbis_info * ov_info(OggVorbis_File *vf, int link)
Definition vorbisfile.c:1906
int ov_pcm_seek(OggVorbis_File *vf, ogg_int64_t pos)
Definition vorbisfile.c:1705
vorbis_comment * ov_comment(OggVorbis_File *vf, int link)
Definition vorbisfile.c:1924
int ov_clear(OggVorbis_File *vf)
Definition vorbisfile.c:972
long ov_read_float(OggVorbis_File *vf, float ***pcm_channels, int length, int *bitstream)
Definition vorbisfile.c:2145
ogg_int64_t ov_pcm_total(OggVorbis_File *vf, int i)
Definition vorbisfile.c:1210
ogg_int64_t ov_pcm_tell(OggVorbis_File *vf)
Definition vorbisfile.c:1871
int ov_open_callbacks(void *f, OggVorbis_File *vf, const char *initial, long ibytes, ov_callbacks callbacks)
Definition vorbisfile.c:1010