mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Committing Paul's spectral nagivation commands patch
From: http://audacity.238276.n2.nabble.com/Patch-spectral-peak-snapping-navigation-commands-td7565648.html
This commit is contained in:
parent
65088dc4d2
commit
2c6401b564
@ -574,7 +574,11 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
c->AddItem(wxT("SelectNone"), _("&None"), FN(OnSelectNone), wxT("Ctrl+Shift+A"));
|
||||
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
c->BeginSubMenu(_("S&pectral"));
|
||||
c->AddItem(wxT("ToggleSpectralSelection"), _("To&ggle spectral selection"), FN(OnToggleSpectralSelection), wxT("Q"));
|
||||
c->AddItem(wxT("NextHigherPeakFrequency"), _("Next Higher Peak Frequency"), FN(OnNextHigherPeakFrequency));
|
||||
c->AddItem(wxT("NextLowerPeakFrequency"), _("Next Lower Peak Frequency"), FN(OnNextLowerPeakFrequency));
|
||||
c->EndSubMenu();
|
||||
#endif
|
||||
|
||||
c->AddItem(wxT("SetLeftSelection"), _("&Left at Playback Position"), FN(OnSetLeftSelection), wxT("["));
|
||||
@ -4728,6 +4732,39 @@ void AudacityProject::OnToggleSpectralSelection()
|
||||
mTrackPanel->Refresh(false);
|
||||
ModifyState(false);
|
||||
}
|
||||
|
||||
void AudacityProject::DoNextPeakFrequency(bool up)
|
||||
{
|
||||
// Find the first selected wave track that is in a spectrogram view.
|
||||
WaveTrack *pTrack = 0;
|
||||
SelectedTrackListOfKindIterator iter(Track::Wave, mTracks);
|
||||
for (Track *t = iter.First(); t; t = iter.Next()) {
|
||||
WaveTrack *const wt = static_cast<WaveTrack*>(t);
|
||||
const int display = wt->GetDisplay();
|
||||
if (display == WaveTrack::SpectrumDisplay ||
|
||||
display == WaveTrack::SpectrumLogDisplay) {
|
||||
pTrack = wt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pTrack) {
|
||||
mTrackPanel->SnapCenterOnce(pTrack, up);
|
||||
mTrackPanel->Refresh(false);
|
||||
ModifyState(false);
|
||||
}
|
||||
}
|
||||
|
||||
void AudacityProject::OnNextHigherPeakFrequency()
|
||||
{
|
||||
DoNextPeakFrequency(true);
|
||||
}
|
||||
|
||||
|
||||
void AudacityProject::OnNextLowerPeakFrequency()
|
||||
{
|
||||
DoNextPeakFrequency(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
void AudacityProject::OnSelectCursorEnd()
|
||||
|
@ -245,6 +245,9 @@ void OnSelectAll();
|
||||
void OnSelectNone();
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
void OnToggleSpectralSelection();
|
||||
void DoNextPeakFrequency(bool up);
|
||||
void OnNextHigherPeakFrequency();
|
||||
void OnNextLowerPeakFrequency();
|
||||
#endif
|
||||
void OnSelectCursorEnd();
|
||||
void OnSelectStartCursor();
|
||||
|
@ -2644,6 +2644,45 @@ inline double findMaxRatio(double center, double rate)
|
||||
|
||||
}
|
||||
|
||||
void TrackPanel::SnapCenterOnce(WaveTrack *pTrack, bool up)
|
||||
{
|
||||
const int windowSize = mTrackArtist->GetSpectrumWindowSize();
|
||||
const double rate = pTrack->GetRate();
|
||||
const double nyq = rate / 2.0;
|
||||
const double binFrequency = rate / windowSize;
|
||||
|
||||
double f1 = mViewInfo->selectedRegion.f1();
|
||||
double centerFrequency = mViewInfo->selectedRegion.fc();
|
||||
if (centerFrequency <= 0) {
|
||||
centerFrequency = up ? binFrequency : nyq;
|
||||
f1 = centerFrequency * sqrt(2.0);
|
||||
}
|
||||
|
||||
const double ratio = f1 / centerFrequency;
|
||||
const int originalBin = floor(0.5 + centerFrequency / binFrequency);
|
||||
const int limitingBin = up ? floor(0.5 + nyq / binFrequency) : 1;
|
||||
|
||||
// This is crude and wasteful, doing the FFT each time the command is called.
|
||||
// It would be better to cache the data, but then invalidation of the cache would
|
||||
// need doing in all places that change the time selection.
|
||||
StartSnappingFreqSelection(pTrack);
|
||||
double snappedFrequency = centerFrequency;
|
||||
int bin = originalBin;
|
||||
if (up) {
|
||||
while (snappedFrequency <= centerFrequency &&
|
||||
bin < limitingBin)
|
||||
snappedFrequency = mFrequencySnapper->FindPeak(++bin * binFrequency, NULL);
|
||||
}
|
||||
else {
|
||||
while (snappedFrequency >= centerFrequency &&
|
||||
bin > limitingBin)
|
||||
snappedFrequency = mFrequencySnapper->FindPeak(--bin * binFrequency, NULL);
|
||||
}
|
||||
|
||||
mViewInfo->selectedRegion.setFrequencies
|
||||
(snappedFrequency / ratio, snappedFrequency * ratio);
|
||||
}
|
||||
|
||||
void TrackPanel::StartSnappingFreqSelection (WaveTrack *pTrack)
|
||||
{
|
||||
static const sampleCount minLength = 8;
|
||||
|
@ -328,6 +328,9 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel {
|
||||
double quietSeekStepPositive, double audioSeekStepPositive);
|
||||
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
public:
|
||||
void SnapCenterOnce (WaveTrack *pTrack, bool up);
|
||||
protected:
|
||||
void StartSnappingFreqSelection (WaveTrack *pTrack);
|
||||
void MoveSnappingFreqSelection (int mouseYCoordinate,
|
||||
int trackTopEdge,
|
||||
|
Loading…
x
Reference in New Issue
Block a user