Skip to content

Commit

Permalink
Update Opus headers and add support for Opus Speech Coding Enhancemen…
Browse files Browse the repository at this point in the history
…t (OSCE).
  • Loading branch information
enzo1982 committed Mar 10, 2024
1 parent 37dea45 commit 92b1021
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 14 deletions.
2 changes: 1 addition & 1 deletion components/decoder/opus/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ VERSION = 1.0
BOCA_PATH = ../../..

# Enter object files here:
OBJECTS = dllinterface.o opus.o
OBJECTS = config.o dllinterface.o opus.o

# Enter additional defines here:
DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support
Expand Down
67 changes: 67 additions & 0 deletions components/decoder/opus/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* BoCA - BonkEnc Component Architecture
* Copyright (C) 2007-2024 Robert Kausch <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */

#include "config.h"

const String BoCA::ConfigureOpus::ConfigID = "OpusDecoder";

BoCA::ConfigureOpus::ConfigureOpus()
{
const Config *config = Config::Get();

complexity = config->GetIntValue(ConfigID, "Complexity", 10);

I18n *i18n = I18n::Get();

i18n->SetContext("Decoders::Opus");

group_quality = new GroupBox(i18n->TranslateString("Quality"), Point(7, 11), Size(286, 41));

text_complexity = new Text(i18n->AddColon(i18n->TranslateString("Complexity")), Point(10, 14));

slider_complexity = new Slider(Point(17 + text_complexity->GetUnscaledTextWidth(), 12), Size(240 - text_complexity->GetUnscaledTextWidth(), 0), OR_HORZ, &complexity, 0, 10);
slider_complexity->onValueChange.Connect(&ConfigureOpus::SetComplexity, this);

text_complexity_value = new Text(NIL, Point(264, 14));

group_quality->Add(text_complexity);
group_quality->Add(slider_complexity);
group_quality->Add(text_complexity_value);

SetComplexity();

Add(group_quality);

SetSize(Size(300, 169));
}

BoCA::ConfigureOpus::~ConfigureOpus()
{
DeleteObject(group_quality);
DeleteObject(text_complexity);
DeleteObject(slider_complexity);
DeleteObject(text_complexity_value);
}

Int BoCA::ConfigureOpus::SaveSettings()
{
Config *config = Config::Get();

config->SetIntValue(ConfigID, "Complexity", complexity);

return Success();
}

Void BoCA::ConfigureOpus::SetComplexity()
{
text_complexity_value->SetText(String::FromInt(complexity));
}
47 changes: 47 additions & 0 deletions components/decoder/opus/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* BoCA - BonkEnc Component Architecture
* Copyright (C) 2007-2024 Robert Kausch <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */

#ifndef H_OPUSCONFIG
#define H_OPUSCONFIG

#include <smooth.h>
#include <boca.h>

using namespace smooth;
using namespace smooth::GUI;

using namespace BoCA;

namespace BoCA
{
class ConfigureOpus : public ConfigLayer
{
private:
GroupBox *group_quality;
Text *text_complexity;
Slider *slider_complexity;
Text *text_complexity_value;

Int complexity;
slots:
Void SetComplexity();
public:
static const String ConfigID;

ConfigureOpus();
~ConfigureOpus();

Int SaveSettings();
};
};

#endif
5 changes: 4 additions & 1 deletion components/decoder/opus/dllinterface.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* BoCA - BonkEnc Component Architecture
* Copyright (C) 2007-2017 Robert Kausch <[email protected]>
* Copyright (C) 2007-2024 Robert Kausch <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -34,6 +34,7 @@ OPUSMULTISTREAMDECODERCREATE ex_opus_multistream_decoder_create = NIL;
OPUSMULTISTREAMDECODE ex_opus_multistream_decode = NIL;
OPUSMULTISTREAMDECODERCTL ex_opus_multistream_decoder_ctl = NIL;
OPUSMULTISTREAMDECODERDESTROY ex_opus_multistream_decoder_destroy = NIL;
OPUSDECODERCTL ex_opus_decoder_ctl = NIL;
OPUSGETVERSIONSTRING ex_opus_get_version_string = NIL;

DynamicLoader *oggdll = NIL;
Expand Down Expand Up @@ -95,12 +96,14 @@ Bool LoadOpusDLL()
ex_opus_multistream_decode = (OPUSMULTISTREAMDECODE) opusdll->GetFunctionAddress("opus_multistream_decode");
ex_opus_multistream_decoder_ctl = (OPUSMULTISTREAMDECODERCTL) opusdll->GetFunctionAddress("opus_multistream_decoder_ctl");
ex_opus_multistream_decoder_destroy = (OPUSMULTISTREAMDECODERDESTROY) opusdll->GetFunctionAddress("opus_multistream_decoder_destroy");
ex_opus_decoder_ctl = (OPUSDECODERCTL) opusdll->GetFunctionAddress("opus_decoder_ctl");
ex_opus_get_version_string = (OPUSGETVERSIONSTRING) opusdll->GetFunctionAddress("opus_get_version_string");

if (ex_opus_multistream_decoder_create == NIL ||
ex_opus_multistream_decode == NIL ||
ex_opus_multistream_decoder_ctl == NIL ||
ex_opus_multistream_decoder_destroy == NIL ||
ex_opus_decoder_ctl == NIL ||
ex_opus_get_version_string == NIL) { FreeOpusDLL(); return False; }

return True;
Expand Down
4 changes: 3 additions & 1 deletion components/decoder/opus/dllinterface.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* BoCA - BonkEnc Component Architecture
* Copyright (C) 2007-2017 Robert Kausch <[email protected]>
* Copyright (C) 2007-2024 Robert Kausch <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand Down Expand Up @@ -61,10 +61,12 @@ typedef OpusMSDecoder * (*OPUSMULTISTREAMDECODERCREATE) (opus_int32, int, in
typedef int (*OPUSMULTISTREAMDECODE) (OpusMSDecoder *, const unsigned char *, opus_int32, opus_int16 *, int, int);
typedef int (*OPUSMULTISTREAMDECODERCTL) (OpusMSDecoder *, int, ...);
typedef void (*OPUSMULTISTREAMDECODERDESTROY) (OpusMSDecoder *);
typedef int (*OPUSDECODERCTL) (OpusDecoder *, int, ...);
typedef const char * (*OPUSGETVERSIONSTRING) ();

extern OPUSMULTISTREAMDECODERCREATE ex_opus_multistream_decoder_create;
extern OPUSMULTISTREAMDECODE ex_opus_multistream_decode;
extern OPUSMULTISTREAMDECODERCTL ex_opus_multistream_decoder_ctl;
extern OPUSMULTISTREAMDECODERDESTROY ex_opus_multistream_decoder_destroy;
extern OPUSDECODERCTL ex_opus_decoder_ctl;
extern OPUSGETVERSIONSTRING ex_opus_get_version_string;
40 changes: 38 additions & 2 deletions components/decoder/opus/opus.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* BoCA - BonkEnc Component Architecture
* Copyright (C) 2007-2021 Robert Kausch <[email protected]>
* Copyright (C) 2007-2024 Robert Kausch <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand All @@ -16,9 +16,12 @@
#include <stdint.h>

#include "opus.h"
#include "config.h"

using namespace smooth::IO;

static Bool osceSupported = False;

const String &BoCA::DecoderOpus::GetComponentSpecs()
{
static String componentSpecs;
Expand All @@ -45,6 +48,12 @@ const String &BoCA::DecoderOpus::GetComponentSpecs()
";

componentSpecs.Replace("%VERSION%", String("v").Append(String(ex_opus_get_version_string()).Replace("libopus ", NIL)));

/* Check availability of Opus Speech Coding Enhancement (OSCE).
*/
const Array<String> &version = String(ex_opus_get_version_string()).Replace("libopus ", NIL).Explode(".");

if (version.GetNth(0).ToInt() > 1 || (version.GetNth(0).ToInt() == 1 && version.GetNth(1).ToInt() >= 5)) osceSupported = True;
}

return componentSpecs;
Expand Down Expand Up @@ -330,6 +339,8 @@ Error BoCA::DecoderOpus::GetStreamInfo(const String &streamURI, Track &track)

BoCA::DecoderOpus::DecoderOpus()
{
configLayer = NIL;

decoder = NIL;

sampleRate = 48000;
Expand All @@ -347,12 +358,19 @@ BoCA::DecoderOpus::DecoderOpus()

BoCA::DecoderOpus::~DecoderOpus()
{
if (configLayer != NIL) Object::DeleteObject(configLayer);
}

Bool BoCA::DecoderOpus::Activate()
{
static Endianness endianness = CPU().GetEndianness();

/* Get configuration.
*/
const Config *config = GetConfiguration();

/* Parse packets and init decoder.
*/
ex_ogg_sync_init(&oy);

Bool initialized = False;
Expand Down Expand Up @@ -403,14 +421,25 @@ Bool BoCA::DecoderOpus::Activate()
else sampleRate = 48000;
}

int error = 0;
int error = OPUS_OK;
unsigned char mapping[2] = { 0, 1 };

if (setup->channel_mapping == 0) decoder = ex_opus_multistream_decoder_create(sampleRate, setup->nb_channels, 1, setup->nb_channels - 1, mapping, &error);
else decoder = ex_opus_multistream_decoder_create(sampleRate, setup->nb_channels, setup->nb_streams, setup->nb_coupled, setup->stream_map, &error);

preSkip = setup->preskip / (48000 / sampleRate);
preSkipLeft = setup->preskip / (48000 / sampleRate);

if (osceSupported && error == OPUS_OK)
{
for (Int i = 0; i < (setup->channel_mapping == 0 ? 1 : setup->nb_streams); i++)
{
OpusDecoder *streamDecoder = NIL;

ex_opus_multistream_decoder_ctl(decoder, OPUS_MULTISTREAM_GET_DECODER_STATE(i, &streamDecoder));
ex_opus_decoder_ctl(streamDecoder, OPUS_SET_COMPLEXITY(config->GetIntValue(ConfigureOpus::ConfigID, "Complexity", 10)));
}
}
}

if (packetNum >= 1) done = True;
Expand Down Expand Up @@ -522,3 +551,10 @@ Int BoCA::DecoderOpus::ReadData(Buffer<UnsignedByte> &data)

return size;
}

ConfigLayer *BoCA::DecoderOpus::GetConfigurationLayer()
{
if (osceSupported && configLayer == NIL) configLayer = new ConfigureOpus();

return configLayer;
}
6 changes: 5 additions & 1 deletion components/decoder/opus/opus.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* BoCA - BonkEnc Component Architecture
* Copyright (C) 2007-2015 Robert Kausch <[email protected]>
* Copyright (C) 2007-2024 Robert Kausch <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Expand All @@ -20,6 +20,8 @@ namespace BoCA
class DecoderOpus : public CS::DecoderComponent
{
private:
ConfigLayer *configLayer;

ogg_sync_state oy;
ogg_stream_state os;
ogg_page og;
Expand Down Expand Up @@ -48,6 +50,8 @@ namespace BoCA
Bool Seek(Int64);

Int ReadData(Buffer<UnsignedByte> &);

ConfigLayer *GetConfigurationLayer();
};
};

Expand Down
Loading

0 comments on commit 92b1021

Please sign in to comment.