Skip to content

Commit

Permalink
Refactor OGG export and always use VBR (#7697)
Browse files Browse the repository at this point in the history
Refactors `AudioFileOgg`, a class used to export to OGG files. There were problems reported of the exported OGG file failing to be played back on some systems. To fix this issue as well as to improve code quality, the class was refactored. In addition, VBR (variable bit rate) is always used, with the quality of the export being determined by a ratio of the selected bit rate and the maximum bit rate allowed. This change naturally occurred when refactoring, though the libvorbisenc documentation recommend VBR for improved audio quality.
  • Loading branch information
sakertooth authored Mar 7, 2025
1 parent c12fd57 commit f44aa3e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 292 deletions.
56 changes: 8 additions & 48 deletions include/AudioFileOgg.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,56 +56,16 @@ class AudioFileOgg : public AudioFileDevice
return new AudioFileOgg( outputSettings, channels, successful, outputFilename, audioEngine );
}


private:
void writeBuffer(const SampleFrame* _ab, const fpp_t _frames) override;

bool startEncoding();
void finishEncoding();
inline int writePage();

inline bitrate_t nominalBitrate() const
{
return getOutputSettings().getBitRateSettings().getBitRate();
}

inline bitrate_t minBitrate() const
{
if (nominalBitrate() > 64)
{
return nominalBitrate() - 64;
}
else
{
return 64;
}
}

inline bitrate_t maxBitrate() const
{
return nominalBitrate() + 64;
}

private:
bool m_ok;
ch_cnt_t m_channels;
sample_rate_t m_rate;

uint32_t m_serialNo;

vorbis_comment * m_comments;

// encoding setup - init by init_ogg_encoding
ogg_stream_state m_os;
ogg_page m_og;
ogg_packet m_op;

vorbis_dsp_state m_vd;
vorbis_block m_vb;
vorbis_info m_vi;

} ;

vorbis_info m_vi;
vorbis_dsp_state m_vds;
vorbis_comment m_vc;
vorbis_block m_vb;
ogg_stream_state m_oss;
ogg_packet m_packet;
ogg_page m_page;
};

} // namespace lmms

Expand Down
46 changes: 11 additions & 35 deletions include/OutputSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,50 +49,26 @@ class OutputSettings
Mono
};

class BitRateSettings
{
public:
BitRateSettings(bitrate_t bitRate, bool isVariableBitRate) :
m_bitRate(bitRate),
m_isVariableBitRate(isVariableBitRate)
{}

bool isVariableBitRate() const { return m_isVariableBitRate; }
void setVariableBitrate(bool variableBitRate = true) { m_isVariableBitRate = variableBitRate; }

bitrate_t getBitRate() const { return m_bitRate; }
void setBitRate(bitrate_t bitRate) { m_bitRate = bitRate; }

private:
bitrate_t m_bitRate;
bool m_isVariableBitRate;
};

public:
OutputSettings( sample_rate_t sampleRate,
BitRateSettings const & bitRateSettings,
BitDepth bitDepth,
StereoMode stereoMode ) :
m_sampleRate(sampleRate),
m_bitRateSettings(bitRateSettings),
m_bitDepth(bitDepth),
m_stereoMode(stereoMode),
m_compressionLevel(0.625) // 5/8
OutputSettings(sample_rate_t sampleRate, bitrate_t bitRate, BitDepth bitDepth, StereoMode stereoMode)
: m_sampleRate(sampleRate)
, m_bitRate(bitRate)
, m_bitDepth(bitDepth)
, m_stereoMode(stereoMode)
, m_compressionLevel(0.625) // 5/8
{
}

OutputSettings( sample_rate_t sampleRate,
BitRateSettings const & bitRateSettings,
BitDepth bitDepth ) :
OutputSettings(sampleRate, bitRateSettings, bitDepth, StereoMode::Stereo )
OutputSettings(sample_rate_t sampleRate, bitrate_t bitRate, BitDepth bitDepth)
: OutputSettings(sampleRate, bitRate, bitDepth, StereoMode::Stereo)
{
}

sample_rate_t getSampleRate() const { return m_sampleRate; }
void setSampleRate(sample_rate_t sampleRate) { m_sampleRate = sampleRate; }

BitRateSettings const & getBitRateSettings() const { return m_bitRateSettings; }
void setBitRateSettings(BitRateSettings const & bitRateSettings) { m_bitRateSettings = bitRateSettings; }
bitrate_t bitrate() const { return m_bitRate; }
void setBitrate(bitrate_t bitrate) { m_bitRate = bitrate; }

BitDepth getBitDepth() const { return m_bitDepth; }
void setBitDepth(BitDepth bitDepth) { m_bitDepth = bitDepth; }
Expand All @@ -109,7 +85,7 @@ class OutputSettings

private:
sample_rate_t m_sampleRate;
BitRateSettings m_bitRateSettings;
bitrate_t m_bitRate;
BitDepth m_bitDepth;
StereoMode m_stereoMode;
double m_compressionLevel;
Expand Down
3 changes: 1 addition & 2 deletions src/core/audio/AudioFileMP3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ bool AudioFileMP3::initEncoder()
lame_set_mode(m_lame, mapToMPEG_mode(stereoMode));

// Handle bit rate settings
OutputSettings::BitRateSettings bitRateSettings = getOutputSettings().getBitRateSettings();
int bitRate = static_cast<int>(bitRateSettings.getBitRate());
int bitRate = static_cast<int>(getOutputSettings().bitrate());

lame_set_VBR(m_lame, vbr_off);
lame_set_brate(m_lame, bitRate);
Expand Down
Loading

0 comments on commit f44aa3e

Please sign in to comment.