1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-02 08:39:46 +02:00

Merge branch 'master' into scrubbing

This commit is contained in:
Paul Licameli 2015-05-26 12:59:52 -04:00
commit 2174de2ea3
11 changed files with 202 additions and 146 deletions

View File

@ -92,6 +92,7 @@ void AboutDialog::CreateCreditsList()
AddCredit(wxT("Jeremy R. Brown"), roleContributor);
AddCredit(wxT("Alex S. Brown"), roleContributor);
AddCredit(wxT("Chris Cannam"), roleContributor);
AddCredit(wxT("Cory Cook"), roleContributor);
AddCredit(wxT("Craig DeForest"), roleContributor);
AddCredit(wxT("Mitch Golden"), roleContributor);
AddCredit(wxT("Brian Gunlogson"), roleContributor);

View File

@ -966,7 +966,9 @@ void AudacityApp::InitLang( const wxString & lang )
//
// 2013-09-13: I've checked this again and it is still required. Still
// no idea why.
#if defined(__WXMAC__)
// 2015-05-26: Disabled the hack since it prevents use of locale specific
// formatting (like comma as decimal separator).
#if defined(__WXMAC__disabled)
wxString oldval;
bool existed;
@ -980,7 +982,7 @@ void AudacityApp::InitLang( const wxString & lang )
mLocale = new wxLocale(wxT(""), lang, wxT(""), true, true);
#endif
#if defined(__WXMAC__)
#if defined(__WXMAC__disabled)
if (existed) {
wxSetEnv(wxT("LANG"), oldval);
}

View File

@ -338,6 +338,8 @@ void BatchProcessDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event))
}
UndoManager *um = project->GetUndoManager();
um->ClearStates();
project->OnSelectAll();
project->OnRemoveTracks();
}
project->OnRemoveTracks();
}

View File

@ -591,7 +591,7 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
PluginDescriptor & plug = iter->second;
PluginType plugType = plug.GetPluginType();
if (plugType != PluginTypeEffect && plugType != PluginTypeNone)
if (plugType != PluginTypeEffect && plugType != PluginTypeStub)
{
continue;
}
@ -610,10 +610,10 @@ void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S)
// This is not right and will not work when other plugin types are added.
// But it's presumed that the plugin manager dialog will be fully developed
// by then.
else if (plugType == PluginTypeNone)
else if (plugType == PluginTypeStub)
{
wxFileName fname = path;
item.name = fname.GetName();
item.name = fname.GetName().Trim(false).Trim(true);
if (!plug.IsValid())
{
item.state = STATE_New;
@ -743,7 +743,7 @@ void PluginRegistrationDialog::SetState(int i, bool toggle, bool state)
ItemData *item = (ItemData *) li.m_data;
// If changing the state of a "New" (placeholder) entry, then we mark it as valid
// If changing the state of a "New" (stub) entry, then we mark it as valid
// since it will either be registered if "Enabled" or ignored if "Disabled".
if (item->state == STATE_New)
{
@ -929,7 +929,7 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
ItemData & item = iter->second;
wxString path = item.path;
if (item.state == STATE_Enabled && item.plug->GetPluginType() == PluginTypeNone)
if (item.state == STATE_Enabled && item.plug->GetPluginType() == PluginTypeStub)
{
enableCount++;
}
@ -952,7 +952,7 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
ItemData & item = iter->second;
wxString path = item.path;
if (item.state == STATE_Enabled && item.plug->GetPluginType() == PluginTypeNone)
if (item.state == STATE_Enabled && item.plug->GetPluginType() == PluginTypeStub)
{
last3 = last3.AfterFirst(wxT('\n')) + item.path + wxT("\n");
status = progress.Update(++i, enableCount, wxString::Format(_("Enabling effect:\n\n%s"), last3.c_str()));
@ -963,12 +963,9 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
if (mm.RegisterPlugin(item.plug->GetProviderID(), path))
{
// Registration successful, so remove the placeholder
PluginMap::iterator iter = pm.mPlugins.find(path);
if (iter != pm.mPlugins.end())
{
pm.mPlugins.erase(iter);
}
// Registration successful, so remove the stub
PluginID ID = item.plug->GetProviderID() + wxT("_") + path;
pm.mPlugins.erase(ID);
}
}
else if (item.state == STATE_New)
@ -1703,16 +1700,12 @@ void PluginManager::Terminate()
void PluginManager::Load()
{
// Get the full scan setting
bool doRescan;
gPrefs->Read(wxT("/Plugins/Rescan"), &doRescan, true);
// Create/Open the registry
mRegistry = new wxFileConfig(wxEmptyString, wxEmptyString, FileNames::PluginRegistry());
// If this group doesn't exist then we have something that's not a registry.
// We should probably warn the user, but it's pretty unlikely that this will happen.
if (!mRegistry->HasGroup(REGROOT) || doRescan)
if (!mRegistry->HasGroup(REGROOT))
{
// Must start over
mRegistry->DeleteAll();
@ -1739,6 +1732,10 @@ void PluginManager::Load()
LoadGroup(PluginTypeExporter);
LoadGroup(PluginTypeImporter);
LoadGroup(PluginTypeStub);
// Not used by 2.1.1 or greater, but must load to allow users to switch between 2.1.0
// and 2.1.1+. This should be removed after a few releases past 2.1.0.
LoadGroup(PluginTypeNone);
delete mRegistry;
@ -1942,9 +1939,16 @@ void PluginManager::LoadGroup(PluginType type)
}
break;
case PluginTypeStub:
{
// Nothing additional for stubs
}
break;
// Not used by 2.1.1 or greater and should be removed after a few releases past 2.1.0.
case PluginTypeNone:
{
// Used for placeholder groups
// Used for stub groups
}
break;
@ -1976,6 +1980,10 @@ void PluginManager::Save()
SaveGroup(PluginTypeEffect);
SaveGroup(PluginTypeExporter);
SaveGroup(PluginTypeImporter);
SaveGroup(PluginTypeStub);
// Not used by 2.1.1 or greater, but must save to allow users to switch between 2.1.0
// and 2.1.1+. This should be removed after a few releases past 2.1.0.
SaveGroup(PluginTypeNone);
// And now the providers
@ -2073,6 +2081,20 @@ void PluginManager::CheckForUpdates()
// Get ModuleManager reference
ModuleManager & mm = ModuleManager::Get();
wxArrayString pathIndex;
for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
{
PluginDescriptor & plug = iter->second;
// Bypass 2.1.0 placeholders...remove this after a few releases past 2.1.0
if (plug.GetPluginType() == PluginTypeNone)
{
continue;
}
pathIndex.Add(plug.GetProviderID() + plug.GetPath().BeforeFirst(wxT(';')));
}
ProviderMap map;
// Always check for and disable missing plugins
@ -2081,14 +2103,19 @@ void PluginManager::CheckForUpdates()
// a job for the plugin manager UI (once it is written).
//
// Also check for plugins that are no longer valid.
PluginMap::iterator iter = mPlugins.begin();
while (iter != mPlugins.end())
for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
{
PluginDescriptor & plug = iter->second;
const PluginID & plugID = plug.GetID();
const wxString & plugPath = plug.GetPath();
PluginType plugType = plug.GetPluginType();
// Bypass 2.1.0 placeholders...remove this after a few releases past 2.1.0
if (plugType == PluginTypeNone)
{
continue;
}
if (plugType == PluginTypeModule)
{
if (!mm.IsProviderValid(plugID, plugPath))
@ -2101,41 +2128,43 @@ void PluginManager::CheckForUpdates()
wxArrayString paths = mm.FindPluginsForProvider(plugID, plugPath);
for (size_t i = 0, cnt = paths.GetCount(); i < cnt; i++)
{
map[paths[i]].Add(plugID);
wxString path = paths[i];
wxASSERT(!path.IsEmpty());
if (pathIndex.Index(plugID + path.BeforeFirst(wxT(';'))) == wxNOT_FOUND)
{
map[path].Add(plugID);
}
}
}
}
else if (plugType != PluginTypeNone)
else if (plugType != PluginTypeNone && plugType != PluginTypeStub)
{
plug.SetValid(mm.IsPluginValid(plug.GetProviderID(), plugPath));
}
++iter;
}
for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
{
PluginDescriptor & plug = iter->second;
const wxString & plugPath = plug.GetPath().BeforeFirst(wxT(';'));
ProviderMap::iterator mapiter = map.find(plugPath);
if (mapiter != map.end())
{
map.erase(mapiter);
}
}
// The provider map now includes only paths that haven't been seen before,
// so create stub descriptors for them.
//
// In 2.1.0, they were called "placeholder" in the registry, but since 2.1.1+
// use them slightly differently, they are not called "stub" in the registry
// and the "placeholder" are left intact. This way switching between 2.1.0
// and 2.1.1+ doesn't cause rescans each time.
for (ProviderMap::iterator iter = map.begin(); iter != map.end(); ++iter)
{
wxString & path = iter->first;
wxArrayString & providers = iter->second;
// Create a descriptor for each provider. Don't know why there would
// be multiple providers for the same path, but might as well.
for (size_t i = 0, cnt = providers.GetCount(); i < cnt; i++)
{
// Create placeholder descriptors to show we've seen this plugin before.
//
// Placeholder descriptors have a plugin type of PluginTypeNone and the ID
// is the path.
PluginDescriptor & plug = mPlugins[path];
plug.SetID(path);
PluginID ID = providers[i] + wxT("_") + path;
// Stub descriptors have a plugin type of PluginTypeNone and the ID
// is the path. They are also marked as disabled and not valid.
PluginDescriptor & plug = mPlugins[ID]; // This will create a new descriptor
plug.SetPluginType(PluginTypeStub);
plug.SetID(ID);
plug.SetProviderID(providers[i]);
plug.SetPath(path);
plug.SetEnabled(false);
@ -2390,6 +2419,9 @@ wxString PluginManager::GetPluginTypeString(PluginType type)
case PluginTypeNone:
str = wxT("Placeholder");
break;
case PluginTypeStub:
str = wxT("Stub");
break;
case PluginTypeEffect:
str = wxT("Effect");
break;

3
src/PluginManager.h Normal file → Executable file
View File

@ -31,7 +31,8 @@
typedef enum
{
PluginTypeNone,
PluginTypeNone = -1, // 2.1.0 placeholder entries...not used by 2.1.1 or greater
PluginTypeStub, // Used for plugins that have not yet been registered
PluginTypeEffect,
PluginTypeExporter,
PluginTypeImporter,

View File

@ -1754,9 +1754,15 @@ void TrackArtist::DrawSpectrum(WaveTrack *track,
}
}
static float sumFreqValues(float *freq, int x0, float bin0, float bin1)
inline
static float sumFreqValues(
const float *freq, int x, int half, float bin0, float bin1,
bool autocorrelation, int range, int gain)
{
const int x0 = x * half;
float value;
#if 0
// Averaging method
if (int(bin1) == int(bin0)) {
value = freq[x0+int(bin0)];
} else {
@ -1768,9 +1774,28 @@ static float sumFreqValues(float *freq, int x0, float bin0, float bin1)
value += freq[x0 + int(bin0)];
bin0 += 1.0;
}
// Do not reference past end of freq array.
if (int(bin1) >= half) {
bin1 -= 1.0;
}
value += freq[x0 + int(bin1)] * (bin1 - int(bin1));
value /= binwidth;
}
#else
// Maximum method, and no apportionment of any single bins over multiple pixel rows
// See Bug971
int bin = floor(0.5 + bin0);
const int limitBin = floor(0.5 + bin1);
value = freq[x0 + bin];
while (++bin < limitBin)
value = std::max(value, freq[x0 + bin]);
#endif
if (!autocorrelation) {
// Last step converts dB to a 0.0-1.0 range
value = (value + range + gain) / (double)range;
}
value = std::min(1.0f, std::max(0.0f, value));
return value;
}
@ -2090,37 +2115,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
float value;
if(!usePxCache) {
if (int (bin1) == int (bin0))
value = freq[half * x + int (bin0)];
else {
float binwidth= bin1 - bin0;
value = freq[half * x + int (bin0)] * (1.f - bin0 + (int)bin0);
bin0 = 1 + int (bin0);
while (bin0 < int (bin1)) {
value += freq[half * x + int (bin0)];
bin0 += 1.0;
}
// Do not reference past end of freq array.
if (int(bin1) >= half) {
bin1 -= 1.0;
}
value += freq[half * x + int (bin1)] * (bin1 - int (bin1));
value /= binwidth;
}
if (!autocorrelation) {
// Last step converts dB to a 0.0-1.0 range
value = (value + range + gain) / (double)range;
}
if (value > 1.0)
value = float(1.0);
if (value < 0.0)
value = float(0.0);
value = sumFreqValues(freq, x, half, bin0, bin1,
autocorrelation, range, gain);
clip->mSpecPxCache->values[x * mid.height + yy] = value;
}
else
@ -2138,7 +2134,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
{
unsigned char rv, gv, bv;
float value;
int x0=x*half;
#ifdef EXPERIMENTAL_FIND_NOTES
int maximas=0;
@ -2256,17 +2251,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrack *track,
value = minColor;
} else
#endif //EXPERIMENTAL_FIND_NOTES
{
value=sumFreqValues(freq, x0, bin0, bin1);
if (!autocorrelation) {
// Last step converts dB to a 0.0-1.0 range
value = (value + gain + range) / (double)range;
}
}
if (value > 1.0)
value = float(1.0);
if (value < 0.0)
value = float(0.0);
value=sumFreqValues(freq, x, half, bin0, bin1,
autocorrelation, range, gain);
clip->mSpecPxCache->values[x * mid.height + yy] = value;
}
else

View File

@ -6196,6 +6196,12 @@ void TrackPanel::HandleResize(wxMouseEvent & event)
/// Handle mouse wheel rotation (for zoom in/out, vertical and horizontal scrolling)
void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
{
if (GetTracks()->IsEmpty())
// Scrolling and Zoom in and out commands are disabled when there are no tracks.
// This should be disabled too for consistency. Otherwise
// you do see changes in the time ruler.
return;
double steps = event.m_wheelRotation /
(event.m_wheelDelta > 0 ? (double)event.m_wheelDelta : 120.0);

View File

@ -470,12 +470,19 @@ void AudioUnitEffectExportDialog::PopulateOrExchange(ShuttleGui & S)
void AudioUnitEffectExportDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
{
// Save active settings
wxString settingsName(wxT("Export Save"));
mEffect->SaveParameters(settingsName);
// Look for selected presets
long sel = mList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
while (sel >= 0)
{
wxString name = mList->GetItemText(sel);
// Make the preset current
mEffect->LoadParameters(mEffect->mHost->GetUserPresetsGroup(name));
// Make sure the user preset directory exists
wxString path;
path.Printf(wxT("%s/%s/%s/%s.aupreset"),
@ -541,6 +548,10 @@ void AudioUnitEffectExportDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
sel = mList->GetNextItem(sel, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
}
// Restore active settings
mEffect->LoadParameters(settingsName);
mEffect->mHost->RemovePrivateConfigSubgroup(settingsName);
EndModal(wxID_OK);
}
@ -654,6 +665,10 @@ void AudioUnitEffectImportDialog::PopulateOrExchange(ShuttleGui & S)
void AudioUnitEffectImportDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
{
// Save active settings
wxString settingsName(wxT("Import Save"));
mEffect->SaveParameters(settingsName);
// Look for selected presets
long sel = -1;
while ((sel = mList->GetNextItem(sel, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) >= 0)
@ -696,9 +711,9 @@ void AudioUnitEffectImportDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
CFPropertyListRef content;
content = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,
xml,
kCFPropertyListImmutable,
NULL);
xml,
kCFPropertyListImmutable,
NULL);
CFRelease(xml);
if (!content)
@ -717,6 +732,10 @@ void AudioUnitEffectImportDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
mEffect->SaveUserPreset(mEffect->mHost->GetUserPresetsGroup(mList->GetItemText(sel)));
}
// Restore active settings
mEffect->LoadParameters(settingsName);
mEffect->mHost->RemovePrivateConfigSubgroup(settingsName);
EndModal(wxID_OK);
}
@ -971,7 +990,6 @@ wxString AudioUnitEffect::GetFamily()
bool AudioUnitEffect::IsInteractive()
{
printf("isinter %d\n", mInteractive);
return mInteractive;
}
@ -2280,42 +2298,6 @@ bool AudioUnitEffect::SetRateAndChannels()
{
ComponentResult auResult;
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Global,
0,
&mSampleRate,
sizeof(Float64));
if (auResult != 0)
{
printf("Didn't accept sample rate\n");
return false;
}
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Input,
0,
&mSampleRate,
sizeof(Float64));
if (auResult != 0)
{
printf("Didn't accept sample rate\n");
return false;
}
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Output,
0,
&mSampleRate,
sizeof(Float64));
if (auResult != 0)
{
printf("Didn't accept sample rate\n");
return false;
}
AudioStreamBasicDescription streamFormat = {0};
streamFormat.mSampleRate = mSampleRate;
@ -2329,27 +2311,71 @@ bool AudioUnitEffect::SetRateAndChannels()
streamFormat.mBytesPerPacket = sizeof(float);
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Global,
0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
&mSampleRate,
sizeof(Float64));
if (auResult != 0)
{
printf("%ls Didn't accept sample rate on global\n", GetName().c_str());
return false;
}
streamFormat.mChannelsPerFrame = mAudioOuts;
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
if (auResult != 0)
if (mAudioIns > 0)
{
return false;
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Input,
0,
&mSampleRate,
sizeof(Float64));
if (auResult != 0)
{
printf("%ls Didn't accept sample rate on input\n", GetName().c_str());
return false;
}
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
if (auResult != 0)
{
printf("%ls didn't accept stream format on input\n", GetName().c_str());
return false;
}
}
if (mAudioOuts > 0)
{
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_SampleRate,
kAudioUnitScope_Output,
0,
&mSampleRate,
sizeof(Float64));
if (auResult != 0)
{
printf("%ls Didn't accept sample rate on output\n", GetName().c_str());
return false;
}
streamFormat.mChannelsPerFrame = mAudioOuts;
auResult = AudioUnitSetProperty(mUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
0,
&streamFormat,
sizeof(AudioStreamBasicDescription));
if (auResult != 0)
{
printf("%ls didn't accept stream format on output\n", GetName().c_str());
return false;
}
}
return true;

2
src/export/ExportPCM.cpp Normal file → Executable file
View File

@ -61,7 +61,7 @@ static const kFormats[] =
{ SF_FORMAT_AIFF | SF_FORMAT_PCM_16, wxT("AIFF"), XO("AIFF (Apple) signed 16-bit PCM") },
{ SF_FORMAT_WAV | SF_FORMAT_PCM_16, wxT("WAV"), XO("WAV (Microsoft) signed 16-bit PCM") },
{ SF_FORMAT_WAV | SF_FORMAT_FLOAT, wxT("WAVFLT"), XO("WAV (Microsoft) 32-bit float PCM") },
{ SF_FORMAT_WAV | SF_FORMAT_GSM610, wxT("GSM610"), XO("GSM 6.10 WAV (mobile)") },
// { SF_FORMAT_WAV | SF_FORMAT_GSM610, wxT("GSM610"), XO("GSM 6.10 WAV (mobile)") },
};
//----------------------------------------------------------------------------

View File

@ -83,7 +83,7 @@ static const wxString preferencePath
(wxT("/GUI/Toolbars/SpectralSelection/CenterAndWidthChoice"));
SpectralSelectionBar::SpectralSelectionBar()
: ToolBar(SpectralSelectionBarID, _("SpectralSelection"), wxT("SpectralSelection"))
: ToolBar(SpectralSelectionBarID, _("Spectral Selection"), wxT("SpectralSelection"))
, mListener(NULL), mbCenterAndWidth(true)
, mCenter(0.0), mWidth(0.0), mLow(0.0), mHigh(0.0)
, mCenterCtrl(NULL), mWidthCtrl(NULL), mLowCtrl(NULL), mHighCtrl(NULL)

4
src/widgets/numformatter.cpp Normal file → Executable file
View File

@ -120,7 +120,7 @@ private:
wxChar NumberFormatter::GetDecimalSeparator()
{
#if defined(WE_DO_NOT_CHANGE_THE_LOCALE_SO_PERIOD_IS_ALWAYS_THE_SEPERATOR) //wxUSE_INTL
#if wxUSE_INTL
// Notice that while using static variable here is not MT-safe, the worst
// that can happen is that we redo the initialization if we're called
// concurrently from more than one thread so it's not a real problem.
@ -158,7 +158,7 @@ wxChar NumberFormatter::GetDecimalSeparator()
bool NumberFormatter::GetThousandsSeparatorIfUsed(wxChar *sep)
{
#if defined(WE_DO_NOT_CHANGE_THE_LOCALE_SO_NO_SEPERATOR) //wxUSE_INTL
#if wxUSE_INTL
static wxChar s_thousandsSeparator = 0;
static LocaleId s_localeUsedForInit;