mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-14 07:37:43 +02:00
Merge branch 'master' into TrackListNode
This commit is contained in:
commit
bb64f4f92c
@ -349,12 +349,74 @@ namespace std {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* template class Maybe<X>
|
* ArrayOf<X>
|
||||||
* Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed.
|
* Not to be confused with std::array (which takes a fixed size) or std::vector
|
||||||
* You might also use it as a member.
|
* This maintains a pointer allocated by NEW X[]. It's cheap: only one pointer,
|
||||||
* Initialize with create(), then use like a smart pointer,
|
* with no size and capacity information for resizing as for vector, and if X is
|
||||||
* with *, ->, get(), reset(), or in if()
|
* a built-in numeric or pointer type, by default there is no zero filling at
|
||||||
*/
|
* allocation time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename X>
|
||||||
|
class ArrayOf : public std::unique_ptr<X[]>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArrayOf() {}
|
||||||
|
explicit ArrayOf(size_t count, bool initialize = false)
|
||||||
|
{
|
||||||
|
if (initialize)
|
||||||
|
reset(safenew X[count]{});
|
||||||
|
else
|
||||||
|
reset(safenew X[count]);
|
||||||
|
}
|
||||||
|
ArrayOf(const ArrayOf&) = delete;
|
||||||
|
ArrayOf& operator= (ArrayOf &&that)
|
||||||
|
{
|
||||||
|
std::unique_ptr<X[]>::operator=(std::move(that));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ArrayOf& operator= (std::unique_ptr<X[]> &&that)
|
||||||
|
{
|
||||||
|
std::unique_ptr<X[]>::operator=(std::move(that));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ArraysOf<X>
|
||||||
|
* This simplifies arrays of arrays, each array separately allocated with NEW[]
|
||||||
|
* But it might be better to use std::Array<ArrayOf<X>, N> for some small constant N
|
||||||
|
* Or use just one array when sub-arrays have a common size and are not large.
|
||||||
|
*/
|
||||||
|
template<typename X>
|
||||||
|
class ArraysOf : public ArrayOf<ArrayOf<X>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ArraysOf() {}
|
||||||
|
explicit ArraysOf(size_t N)
|
||||||
|
: ArrayOf<ArrayOf<X>>( N )
|
||||||
|
{}
|
||||||
|
ArraysOf(size_t N, size_t M, bool initialize = false)
|
||||||
|
: ArrayOf<ArrayOf<X>>( N )
|
||||||
|
{
|
||||||
|
for (size_t ii = 0; ii < N; ++ii)
|
||||||
|
(*this)[ii] = ArrayOf<X>{ M, initialize };
|
||||||
|
}
|
||||||
|
ArraysOf(const ArraysOf&) = delete;
|
||||||
|
ArraysOf& operator= (ArraysOf&& that)
|
||||||
|
{
|
||||||
|
ArrayOf<ArrayOf<X>>::operator=(std::move(that));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* template class Maybe<X>
|
||||||
|
* Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed.
|
||||||
|
* You might also use it as a member.
|
||||||
|
* Initialize with create(), then use like a smart pointer,
|
||||||
|
* with *, ->, get(), reset(), or in if()
|
||||||
|
*/
|
||||||
|
|
||||||
// Placement-new is used below, and that does not cooperate with the DEBUG_NEW for Visual Studio
|
// Placement-new is used below, and that does not cooperate with the DEBUG_NEW for Visual Studio
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#include <wx/defs.h>
|
#include <wx/defs.h>
|
||||||
|
|
||||||
#include <wx/choice.h>
|
#include <wx/choice.h>
|
||||||
|
#include <wx/checkbox.h>
|
||||||
#include <wx/dynlib.h>
|
#include <wx/dynlib.h>
|
||||||
#include <wx/ffile.h>
|
#include <wx/ffile.h>
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
@ -110,6 +111,7 @@
|
|||||||
|
|
||||||
#define CHANNEL_JOINT 0
|
#define CHANNEL_JOINT 0
|
||||||
#define CHANNEL_STEREO 1
|
#define CHANNEL_STEREO 1
|
||||||
|
#define CHANNEL_MONO 2
|
||||||
|
|
||||||
#define QUALITY_0 0
|
#define QUALITY_0 0
|
||||||
#define QUALITY_1 1
|
#define QUALITY_1 1
|
||||||
@ -211,6 +213,7 @@ static CHOICES sampRates[] =
|
|||||||
#define ID_ABR 7002
|
#define ID_ABR 7002
|
||||||
#define ID_CBR 7003
|
#define ID_CBR 7003
|
||||||
#define ID_QUALITY 7004
|
#define ID_QUALITY 7004
|
||||||
|
#define ID_MONO 7005
|
||||||
|
|
||||||
static void InitMP3_Statics()
|
static void InitMP3_Statics()
|
||||||
{
|
{
|
||||||
@ -275,6 +278,7 @@ public:
|
|||||||
void OnABR(wxCommandEvent& evt);
|
void OnABR(wxCommandEvent& evt);
|
||||||
void OnCBR(wxCommandEvent& evt);
|
void OnCBR(wxCommandEvent& evt);
|
||||||
void OnQuality(wxCommandEvent& evt);
|
void OnQuality(wxCommandEvent& evt);
|
||||||
|
void OnMono(wxCommandEvent& evt);
|
||||||
|
|
||||||
void LoadNames(CHOICES *choices, int count);
|
void LoadNames(CHOICES *choices, int count);
|
||||||
wxArrayString GetNames(CHOICES *choices, int count);
|
wxArrayString GetNames(CHOICES *choices, int count);
|
||||||
@ -285,6 +289,7 @@ private:
|
|||||||
|
|
||||||
wxRadioButton *mStereo;
|
wxRadioButton *mStereo;
|
||||||
wxRadioButton *mJoint;
|
wxRadioButton *mJoint;
|
||||||
|
wxCheckBox *mMono;
|
||||||
wxRadioButton *mSET;
|
wxRadioButton *mSET;
|
||||||
wxRadioButton *mVBR;
|
wxRadioButton *mVBR;
|
||||||
wxRadioButton *mABR;
|
wxRadioButton *mABR;
|
||||||
@ -306,6 +311,7 @@ BEGIN_EVENT_TABLE(ExportMP3Options, wxPanel)
|
|||||||
EVT_RADIOBUTTON(ID_ABR, ExportMP3Options::OnABR)
|
EVT_RADIOBUTTON(ID_ABR, ExportMP3Options::OnABR)
|
||||||
EVT_RADIOBUTTON(ID_CBR, ExportMP3Options::OnCBR)
|
EVT_RADIOBUTTON(ID_CBR, ExportMP3Options::OnCBR)
|
||||||
EVT_CHOICE(wxID_ANY, ExportMP3Options::OnQuality)
|
EVT_CHOICE(wxID_ANY, ExportMP3Options::OnQuality)
|
||||||
|
EVT_CHECKBOX(ID_MONO, ExportMP3Options::OnMono)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -403,14 +409,21 @@ void ExportMP3Options::PopulateOrExchange(ShuttleGui & S)
|
|||||||
mMode->Enable(enable);
|
mMode->Enable(enable);
|
||||||
|
|
||||||
S.AddPrompt(_("Channel Mode:"));
|
S.AddPrompt(_("Channel Mode:"));
|
||||||
S.StartTwoColumn();
|
S.StartMultiColumn(3, wxEXPAND);
|
||||||
{
|
{
|
||||||
|
bool mono = false;
|
||||||
|
gPrefs->Read(wxT("/FileFormats/MP3ForceMono"), &mono, 0);
|
||||||
|
|
||||||
S.StartRadioButtonGroup(wxT("/FileFormats/MP3ChannelMode"), CHANNEL_JOINT);
|
S.StartRadioButtonGroup(wxT("/FileFormats/MP3ChannelMode"), CHANNEL_JOINT);
|
||||||
{
|
{
|
||||||
mJoint = S.TieRadioButton(_("Joint Stereo"), CHANNEL_JOINT);
|
mJoint = S.TieRadioButton(_("Joint Stereo"), CHANNEL_JOINT);
|
||||||
mStereo = S.TieRadioButton(_("Stereo"), CHANNEL_STEREO);
|
mStereo = S.TieRadioButton(_("Stereo"), CHANNEL_STEREO);
|
||||||
|
mJoint->Enable(!mono);
|
||||||
|
mStereo->Enable(!mono);
|
||||||
}
|
}
|
||||||
S.EndRadioButtonGroup();
|
S.EndRadioButtonGroup();
|
||||||
|
|
||||||
|
mMono = S.Id(ID_MONO).AddCheckBox(_("Force export to mono"), mono? wxT("true") : wxT("false"));
|
||||||
}
|
}
|
||||||
S.EndTwoColumn();
|
S.EndTwoColumn();
|
||||||
}
|
}
|
||||||
@ -506,6 +519,17 @@ void ExportMP3Options::OnQuality(wxCommandEvent& WXUNUSED(event))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportMP3Options::OnMono(wxCommandEvent& evt)
|
||||||
|
{
|
||||||
|
bool mono = false;
|
||||||
|
mono = mMono->GetValue();
|
||||||
|
mJoint->Enable(!mono);
|
||||||
|
mStereo->Enable(!mono);
|
||||||
|
|
||||||
|
gPrefs->Write(wxT("/FileFormats/MP3ForceMono"), mono);
|
||||||
|
gPrefs->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
void ExportMP3Options::LoadNames(CHOICES *choices, int count)
|
void ExportMP3Options::LoadNames(CHOICES *choices, int count)
|
||||||
{
|
{
|
||||||
mRate->Clear();
|
mRate->Clear();
|
||||||
@ -1265,7 +1289,8 @@ int MP3Exporter::InitializeStream(int channels, int sampleRate)
|
|||||||
|
|
||||||
// Set the channel mode
|
// Set the channel mode
|
||||||
MPEG_mode mode;
|
MPEG_mode mode;
|
||||||
if (channels == 1) {
|
|
||||||
|
if (channels == 1 || mChannel == CHANNEL_MONO) {
|
||||||
mode = MONO;
|
mode = MONO;
|
||||||
}
|
}
|
||||||
else if (mChannel == CHANNEL_JOINT) {
|
else if (mChannel == CHANNEL_JOINT) {
|
||||||
@ -1668,11 +1693,13 @@ int ExportMP3::Export(AudacityProject *project,
|
|||||||
int rmode;
|
int rmode;
|
||||||
int vmode;
|
int vmode;
|
||||||
int cmode;
|
int cmode;
|
||||||
|
bool forceMono;
|
||||||
|
|
||||||
gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), &brate, 128);
|
gPrefs->Read(wxT("/FileFormats/MP3Bitrate"), &brate, 128);
|
||||||
gPrefs->Read(wxT("/FileFormats/MP3RateMode"), &rmode, MODE_CBR);
|
gPrefs->Read(wxT("/FileFormats/MP3RateMode"), &rmode, MODE_CBR);
|
||||||
gPrefs->Read(wxT("/FileFormats/MP3VarMode"), &vmode, ROUTINE_FAST);
|
gPrefs->Read(wxT("/FileFormats/MP3VarMode"), &vmode, ROUTINE_FAST);
|
||||||
gPrefs->Read(wxT("/FileFormats/MP3ChannelMode"), &cmode, CHANNEL_STEREO);
|
gPrefs->Read(wxT("/FileFormats/MP3ChannelMode"), &cmode, CHANNEL_STEREO);
|
||||||
|
gPrefs->Read(wxT("/FileFormats/MP3ForceMono"), &forceMono, 0);
|
||||||
|
|
||||||
// Set the bitrate/quality and mode
|
// Set the bitrate/quality and mode
|
||||||
if (rmode == MODE_SET) {
|
if (rmode == MODE_SET) {
|
||||||
@ -1722,7 +1749,10 @@ int ExportMP3::Export(AudacityProject *project,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the channel mode
|
// Set the channel mode
|
||||||
if (cmode == CHANNEL_JOINT) {
|
if (forceMono) {
|
||||||
|
exporter.SetChannel(CHANNEL_MONO);
|
||||||
|
}
|
||||||
|
else if (cmode == CHANNEL_JOINT) {
|
||||||
exporter.SetChannel(CHANNEL_JOINT);
|
exporter.SetChannel(CHANNEL_JOINT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user