24#include "../../../ui/BrushHandle.h"
30#include "../../../../TrackArt.h"
31#include "../../../../TrackArtist.h"
32#include "../../../../TrackPanelDrawingContext.h"
40#include <wx/dcmemory.h>
41#include <wx/graphics.h>
50 "Broken correspondence");
54 {
wxT(
"Spectrogram"),
XXO(
"&Spectrogram") }
87 std::make_shared<SpectralData>(pOldData->GetSR());
88 pNewData->CopyFrom(*pOldData);
89 pOldData->clearAllData();
93 if (&
mView == &view) {
95 std::make_shared<SpectralData>(pOldData->GetSR());
96 pNewData->CopyFrom( *pOldData );
115 view.mpSpectralData->CopyFrom(*pBackupData);
130 std::weak_ptr<BrushHandle> &holder,
132 const std::shared_ptr<SpectrumView> &pChannelView,
133 const std::shared_ptr<SpectralData> &mpData)
137 auto result = std::make_shared<BrushHandle>(
138 std::make_shared<SpectrumView::SpectralDataSaver>(*pChannelView),
140 st, viewInfo, mpData, projectSettings);
145 const auto pChannel = pChannelView->FindWaveChannel();
147 !pChannel->GetTrack().GetSelected())
161 for (
auto pChannel : wt->Channels()) {
162 if (
auto pWaveChannelView =
164 for (
const auto &pSubView : pWaveChannelView->GetAllSubViews()) {
165 if (
const auto sView =
dynamic_cast<SpectrumView*
>(pSubView.get()))
178 std::vector<UIHandlePtr> results;
180#ifdef EXPERIMENTAL_BRUSH_TOOL
185 pProject, std::static_pointer_cast<SpectrumView>(shared_from_this()),
187 results.push_back(result);
193 state, pProject, currentTool, bMultiTool, wt
204 gPrefs->
Read(
wxT(
"/GUI/CollapseToHalfWave"), &bHalfWave,
false);
205 if( bHalfWave && minimized)
211 constexpr auto max = std::numeric_limits<float>::max();
212 const bool spectrumLinear =
217 .
SetBounds( spectrumLinear ? 0.0f : 1.0f, max );
230 return std::make_shared<SpectrumVRulerControls>(shared_from_this());
239 if (
const auto pDest =
dynamic_cast< SpectrumView*
>(destSubView)) {
240 pDest->mpSpectralData =
250(
const float *spectrum,
float bin0,
float bin1,
unsigned nBins,
251 bool autocorrelation,
int gain,
int range)
258 if ((
int)(bin1) == (
int)(bin0)) {
259 value = spectrum[(int)(bin0)];
261 float binwidth= bin1 - bin0;
262 value = spectrum[(int)(bin0)] * (1.f - bin0 + (int)bin0);
264 bin0 = 1 + (int)(bin0);
265 while (bin0 < (
int)(bin1)) {
266 value += spectrum[(int)(bin0)];
270 if ((
int)(bin1) >= (
int)nBins) {
274 value += spectrum[(int)(bin1)] * (bin1 - (int)(bin1));
280 int index, limitIndex;
281 if (autocorrelation) {
284 index = std::max(0.0f,
std::min(
float(nBins - 1),
285 (nBins - 1) - (2 * nBins) / (std::max(1.0f, bin0))
287 limitIndex = std::max(0.0f,
std::min(
float(nBins - 1),
288 (nBins - 1) - (2 * nBins) / (std::max(1.0f, bin1))
292 index = std::min<int>(nBins - 1, (
int)(floor(0.5 + bin0)));
293 limitIndex = std::min<int>(nBins, (
int)(floor(0.5 + bin1)));
295 value = spectrum[index];
296 while (++index < limitIndex)
297 value = std::max(value, spectrum[index]);
299 if (!autocorrelation) {
301 value = (value + range + gain) / (
double)range;
303 value =
std::min(1.0f, std::max(0.0f, value));
310 float selBinCenter,
float selBinHi,
int dashCount,
bool isSpectral )
314 if ((selBinCenter >= 0) && (bin0 <= selBinCenter) &&
315 (selBinCenter < bin1))
317 if ((0 == dashCount % 2) &&
318 (((selBinLo >= 0) && (bin0 <= selBinLo) && ( selBinLo < bin1)) ||
319 ((selBinHi >= 0) && (bin0 <= selBinHi) && ( selBinHi < bin1))))
321 if ((selBinLo < 0 || selBinLo < bin1) && (selBinHi < 0 || selBinHi > bin0))
329 bool trackIsSelected)
331 if (!trackIsSelected)
333 const double t0 = selectedRegion.
t0();
334 const double t1 = selectedRegion.
t1();
337 auto s1 = std::clamp(
346 const std::shared_ptr<SpectralData> &mpSpectralData,
349 auto &dc = context.
dc;
351 bool onBrushTool = artist->onBrushTool;
352 const auto &selectedRegion = *artist->pSelectedRegion;
353 const auto &zoomInfo = *artist->pZoomInfo;
355#ifdef PROFILE_WAVEFORM
371 enum { DASH_LENGTH = 10 };
374 const wxRect &hiddenMid =
params.hiddenMid;
377 if (hiddenMid.width <= 0) {
381 const double &t0 =
params.t0;
386 const double &averagePixelsPerSecond =
params.averagePixelsPerSecond;
389 const double &hiddenLeftOffset =
params.hiddenLeftOffset;
390 const double &leftOffset =
params.leftOffset;
391 const wxRect &mid =
params.mid;
395 freqLo = selectedRegion.f0();
396 freqHi = selectedRegion.f1();
398 const int &colorScheme =
settings.colorScheme;
402#ifdef EXPERIMENTAL_FIND_NOTES
403 const bool &fftFindNotes =
settings.fftFindNotes;
404 const double &findNotesMinA =
settings.findNotesMinA;
405 const int &numberOfMaxima =
settings.numberOfMaxima;
406 const bool &findNotesQuantize =
settings.findNotesQuantize;
408#ifdef EXPERIMENTAL_FFT_Y_GRID
409 const bool &fftYGrid =
settings.fftYGrid;
412 dc.SetPen(*wxTRANSPARENT_PEN);
418 wxImage image((
int)mid.width, (
int)mid.height);
421#ifdef EXPERIMENTAL_SPECTROGRAM_OVERLAY
423 unsigned char *alpha = image.GetAlpha();
425 unsigned char *data = image.GetData();
427 const auto half =
settings.GetFFTLength() / 2;
428 const double binUnit =
sampleRate / (2 * half);
429 const float *freq = 0;
432 clip, freq,
settings, where, (
size_t)hiddenMid.width, t0,
433 averagePixelsPerSecond);
436 float minFreq, maxFreq;
443 float *bins = (
float*)alloca(
sizeof(*bins)*(hiddenMid.height + 1));
448 float nextBin = std::max( 0.0f,
std::min(
float(nBins - 1),
449 settings.findBin( *it, binUnit ) ) );
452 for (yy = 0; yy < hiddenMid.height; ++yy) {
454 nextBin = std::max( 0.0f,
std::min(
float(nBins - 1),
455 settings.findBin( *++it, binUnit ) ) );
460#ifdef EXPERIMENTAL_FFT_Y_GRID
463 scale2 = (lmax - lmin) / log2,
467 for (
int yy = 0; yy < mid.height; ++yy) {
468 float n = (float(yy) / mid.height*scale2 - lmin2) * 12;
469 float n2 = (float(yy + 1) / mid.height*scale2 - lmin2) * 12;
470 float f = float(minFreq) / (fftSkipPoints + 1)*powf(2.0f, n / 12.0f + lmin2);
471 float f2 = float(minFreq) / (fftSkipPoints + 1)*powf(2.0f, n2 / 12.0f + lmin2);
472 n = logf(f / 440) / log2 * 12;
473 n2 = logf(f2 / 440) / log2 * 12;
474 if (floor(n) < floor(n2))
483 if (!updated && specPxCache &&
484 ((
int)specPxCache->len == hiddenMid.height * hiddenMid.width)
485 && scaleType == specPxCache->scaleType
486 && gain == specPxCache->gain
487 && range == specPxCache->range
488 && minFreq == specPxCache->minFreq
489 && maxFreq == specPxCache->maxFreq
490#ifdef EXPERIMENTAL_FFT_Y_GRID
491 && fftYGrid==fftYGridOld
493#ifdef EXPERIMENTAL_FIND_NOTES
494 && fftFindNotes == artist->fftFindNotesOld
495 && findNotesMinA == artist->findNotesMinAOld
496 && numberOfMaxima == artist->findNotesNOld
497 && findNotesQuantize == artist->findNotesQuantizeOld
505 specPxCache = std::make_unique<SpecPxCache>(hiddenMid.width * hiddenMid.height);
506 specPxCache->scaleType = scaleType;
507 specPxCache->gain = gain;
508 specPxCache->range = range;
509 specPxCache->minFreq = minFreq;
510 specPxCache->maxFreq = maxFreq;
511#ifdef EXPERIMENTAL_FIND_NOTES
512 artist->fftFindNotesOld = fftFindNotes;
513 artist->findNotesMinAOld = findNotesMinA;
514 artist->findNotesNOld = numberOfMaxima;
515 artist->findNotesQuantizeOld = findNotesQuantize;
518#ifdef EXPERIMENTAL_FIND_NOTES
519 float log2 = logf( 2.0f ),
520 lmin = logf( minFreq ), lmax = logf( maxFreq ), scale = lmax - lmin,
526#ifdef EXPERIMENTAL_FIND_NOTES
528 float maxima0[128], maxima1[128];
531 bin2f = 1.0f / f2bin,
532 minDistance = powf(2.0f, 2.0f / 12.0f),
533 i0 = expf(lmin) / binUnit,
534 i1 = expf(scale + lmin) / binUnit,
536 const size_t maxTableSize = 1024;
541#pragma omp parallel for
543 for (
int xx = 0; xx < hiddenMid.width; ++xx) {
544#ifdef EXPERIMENTAL_FIND_NOTES
546 const int x0 = nBins * xx;
548 for (
int i = maxTableSize - 1; i >= 0; i--)
552 for (
int i = (
int)(i0); i < (int)(i1); i++) {
553 float freqi = freq[x0 + (int)(i)];
554 int value = (int)((freqi + gain + range) / range*(maxTableSize - 1));
557 if (value >= maxTableSize)
558 value = maxTableSize - 1;
562 for (
int i = maxTableSize - 1; i >= 0; i--) {
563 int index = indexes[i];
565 float freqi = freq[x0 + index];
566 if (freqi < findNotesMinA)
570 for (
int m = 0; m < maximas; m++) {
572 float maxm = maxima[m];
573 if (maxm / index < minDistance && index / maxm < minDistance) {
579 maxima[maximas++] = index;
580 if (maximas >= numberOfMaxima)
587#define f2pix(f) (logf(f)-lmins)/(lmaxs-lmins)*hiddenMid.height
590 for (
int i = 0; i < maximas; i++) {
591 int index = maxima[i];
592 float f = float(index)*bin2f;
593 if (findNotesQuantize)
595 f = expf((
int)(log(f / 440) / log2 * 12 - 0.5) / 12.0f*log2) * 440;
598 float f0 = expf((log(f / 440) / log2 * 24 - 1) / 24.0f*log2) * 440;
599 maxima0[i] = f2pix(f0);
600 float f1 = expf((log(f / 440) / log2 * 24 + 1) / 24.0f*log2) * 440;
601 maxima1[i] = f2pix(f1);
606 bool inMaximum =
false;
609 for (
int yy = 0; yy < hiddenMid.height; ++yy) {
610 const float bin = bins[yy];
611 const float nextBin = bins[yy+1];
615 (freq + nBins * xx, bin, nextBin, nBins, autocorrelation, gain, range);
616 specPxCache->values[xx * hiddenMid.height + yy] = value;
621#ifdef EXPERIMENTAL_FIND_NOTES
624 float i0 = maxima0[it];
629 float i1 = maxima1[it];
631 value =
findValue(freq + x0, bin, nextBin, nBins, autocorrelation, gain, range);
632 if (value < findNotesMinA)
652 (freq + nBins * xx, bin, nextBin, nBins, autocorrelation, gain, range);
654 specPxCache->values[xx * hiddenMid.height + yy] = value;
660 float selBinLo =
settings.findBin( freqLo, binUnit);
661 float selBinHi =
settings.findBin( freqHi, binUnit);
662 float selBinCenter = (freqLo < 0 || freqHi < 0)
666 const bool isSpectral =
settings.SpectralSelectionEnabled();
668 const int begin = hidden
670 : std::max(0, (
int)(zoomInfo.GetFisheyeLeftBoundary(-leftOffset)));
671 const int end = hidden
673 :
std::min(mid.width, (
int)(zoomInfo.GetFisheyeRightBoundary(-leftOffset)));
674 const size_t numPixels = std::max(0,
end -
begin);
682 for (
int ii =
begin; ii <
end; ++ii) {
683 const double time = zoomInfo.PositionToTime(ii, -leftOffset) - playStartTime;
698 int fisheyeLeft = zoomInfo.GetFisheyeLeftBoundary(-leftOffset);
701 int selectedX = zoomInfo.TimeToPosition(selectedRegion.t0(), -leftOffset);
704#pragma omp parallel for
708 int windowSize = mpSpectralData->GetWindowSize();
709 int hopSize = mpSpectralData->GetHopSize();
710 double sr = mpSpectralData->GetSR();
711 auto &dataHistory = mpSpectralData->dataHistory;
714 dataHistory.push_back(mpSpectralData->dataBuffer);
717 std::map<long long, std::set<int>> hopBinMap;
718 for(
auto vecIter = dataHistory.begin(); vecIter != dataHistory.end(); ++vecIter){
719 for(
const auto &hopMap: *vecIter){
720 for(
const auto &binNum: hopMap.second)
721 hopBinMap[hopMap.first].insert(binNum);
726 auto yyToFreqBin = [&](
int yy){
727 const double p = double(yy) / hiddenMid.height;
729 float convertedFreqBinNum = convertedFreq / (sr / windowSize);
735 return static_cast<int>(
lrintf(convertedFreqBinNum));
738 for (
int xx = 0; xx < mid.width; ++xx) {
739 int correctedX = xx + leftOffset - hiddenLeftOffset;
744 if (!zoomInfo.InFisheye(xx, -leftOffset)) {
748 int specIndex = (xx - fisheyeLeft) * nBins;
749 wxASSERT(specIndex >= 0 && specIndex < (
int)specCache.
freq.size());
750 uncached = &specCache.
freq[specIndex];
757 (zoomInfo.PositionToTime(xx, -leftOffset) - playStartTime));
761 (zoomInfo.PositionToTime(xx + 1, -leftOffset) - playStartTime));
763 bool maybeSelected = ssel0 <= w0 && w1 < ssel1;
764 maybeSelected = maybeSelected || (xx == selectedX);
767 std::set<int> *pSelectedBins =
nullptr;
768 std::set<int>::iterator freqBinIter;
769 auto advanceFreqBinIter = [&](
int nextBinRounded){
770 while (freqBinIter != pSelectedBins->end() &&
771 *freqBinIter < nextBinRounded)
775 bool hitHopNum =
false;
777 int convertedHopNum = (w0.as_long_long() + hopSize / 2) / hopSize;
778 hitHopNum = (hopBinMap.find(convertedHopNum) != hopBinMap.end());
780 pSelectedBins = &hopBinMap[convertedHopNum];
781 freqBinIter = pSelectedBins->begin();
782 advanceFreqBinIter(yyToFreqBin(0));
786 for (
int yy = 0; yy < hiddenMid.height; ++yy) {
788 maybeSelected =
false;
789 const float bin = bins[yy];
790 const float nextBin = bins[yy+1];
791 auto binRounded = yyToFreqBin(yy);
792 auto nextBinRounded = yyToFreqBin(yy + 1);
795 && freqBinIter != pSelectedBins->end()
796 && binRounded == *freqBinIter)
797 maybeSelected =
true;
800 advanceFreqBinIter(nextBinRounded);
812 (xx + leftOffset - hiddenLeftOffset) / DASH_LENGTH, isSpectral);
818 const float value = uncached
819 ?
findValue(uncached, bin, nextBin, nBins, autocorrelation, gain, range)
820 : specPxCache->values[correctedX * hiddenMid.height + yy];
822 unsigned char rv, gv, bv;
825#ifdef EXPERIMENTAL_FFT_Y_GRID
826 if (fftYGrid && yGrid[yy]) {
832 int px = ((mid.height - 1 - yy) * mid.width + xx);
833#ifdef EXPERIMENTAL_SPECTROGRAM_OVERLAY
835 alpha[px]= wxMin( 200, (value+0.3) * 500) ;
844 dataHistory.pop_back();
845 wxBitmap converted = wxBitmap(image);
849 memDC.SelectObject(converted);
851 dc.Blit(mid.x, mid.y, mid.width, mid.height, &memDC, 0, 0, wxCOPY, FALSE);
867 const auto &blankSelectedBrush = artist->blankSelectedBrush;
868 const auto &blankBrush = artist->blankBrush;
870 context, rect, channel, blankSelectedBrush, blankBrush );
872 for (
const auto &pInterval : channel.
Intervals()) {
873 bool selected = selectedClip &&
874 selectedClip == &pInterval->GetClip();
887 const auto &pendingTracks = *artist->pPendingTracks;
889 auto &dc = context.
dc;
895 pendingTracks.SubstitutePendingChangedChannel(*pChannel));
897#if defined(__WXMAC__)
898 wxAntialiasMode aamode = dc.GetGraphicsContext()->GetAntialiasMode();
899 dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE);
903 wxASSERT(waveChannelView.use_count());
905 auto selectedClip = waveChannelView->GetSelectedClip();
906 DoDraw(context, wt, selectedClip.get(), rect);
908#if defined(__WXMAC__)
909 dc.GetGraphicsContext()->SetAntialiasMode(aamode);
917 return std::make_shared<SpectrumView>(view);
926#include "../../../../MenuCreator.h"
928#include "../../../../RefreshCode.h"
929#include "../../../../prefs/PrefsDialog.h"
930#include "../../../../prefs/SpectrumPrefs.h"
932#include "../../../../widgets/PopupMenuTable.h"
944 void OnSpectrogramSettings(wxCommandEvent &);
952void SpectrogramSettingsHandler::OnSpectrogramSettings(wxCommandEvent &)
954 class ViewSettingsDialog final :
public PrefsDialog
979 if (gAudioIO->IsBusy()){
982"To change Spectrogram Settings, stop any\n playing or recording first."),
983 XO(
"Stop the Audio First"),
984 wxOK | wxICON_EXCLAMATION | wxCENTRE);
988 auto &wc = **
static_cast<WaveTrack&
>(mpData->track).Channels().begin();
997 auto title =
XO(
"%s:").Format(wc.GetTrack().GetName());
998 ViewSettingsDialog dialog(
999 mpData->pParent, mpData->project,
title, factories, page);
1001 if (0 != dialog.ShowModal()) {
1015 {
"SubViews/Extra" },
1016 std::make_unique<PopupMenuSection>(
"SpectrogramSettings",
1018 PopupMenuTable::Adapt< WaveTrackPopupMenuTable >(
1022 static const int OnSpectrogramSettingsID =
1027 const auto displays = view.GetDisplays();
1028 bool hasSpectrum = (displays.end() != std::find(
1029 displays.begin(), displays.end(),
1031 WaveChannelViewConstants::Spectrum, {} }
1039 ? std::make_unique<Entry>(
"SpectrogramSettings",
1041 OnSpectrogramSettingsID,
1042 XXO(
"S&pectrogram Settings..."),
1043 (wxCommandEventFunction)
1044 (&SpectrogramSettingsHandler::OnSpectrogramSettings),
1045 SpectrogramSettingsHandler::Instance(),
1050 menu.Enable(
id, !gAudioIO->IsBusy());
1059 const auto keyCode =
event.GetKeyCode();
1061 (keyCode == WXK_BACK || keyCode == WXK_DELETE ||
1062 keyCode == WXK_NUMPAD_DELETE)
1070 event.Skip(!capture);
1077 event.Skip(!capture);
1088 event.Skip(!capture);
1093#include "../../../ui/SelectHandle.h"
1094#include "../../../../CommonCommandFlags.h"
1110 const auto hasSpectrum = [](
const WaveTrack *wt){
1112 return displays.end() != std::find(
1113 displays.begin(), displays.end(),
1117 const auto iter = find_if(
begin(range),
end(range), hasSpectrum);
1118 if (iter !=
end(range)) {
1122 viewInfo, **wt.Channels().first, up);
1138 const double f0 = selectedRegion.
f0();
1139 const double f1 = selectedRegion.f1();
1140 const bool haveSpectralSelection =
1143 if (haveSpectralSelection)
1147 selectedRegion.setFrequencies
1151 selectedRegion.setFrequencies(mLastF0, mLastF1);
1173 return std::make_unique< Handler >(); } };
1180#define FN(X) (& Handler :: X)
1184 static auto menu = std::shared_ptr{
1188 XXO(
"To&ggle Spectral Selection"),
FN(OnToggleSpectralSelection),
1191 XXO(
"Next &Higher Peak Frequency"),
FN(OnNextHigherPeakFrequency),
1194 XXO(
"Next &Lower Peak Frequency"),
FN(OnNextLowerPeakFrequency),
1203 Placement{
wxT(
"Select/Basic"), { OrderingHint::After,
wxT(
"Region") } }
void GetColorGradient(float value, AColor::ColorGradientChoice selected, int colorScheme, unsigned char *__restrict red, unsigned char *__restrict green, unsigned char *__restrict blue)
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
AttachedItem sAttachment2
std::shared_ptr< UIHandle > UIHandlePtr
wxEvtHandler CommandHandlerObject
const ReservedCommandFlag & TracksExistFlag()
EffectDistortionSettings params
XXO("&Cut/Copy/Paste Toolbar")
audacity::BasicSettings * gPrefs
PrefsPanel::Factory SpectrumPrefsFactory(WaveChannel *wc)
static WaveChannelSubViewType::RegisteredType reg
static const WaveChannelSubViews::RegisteredFactory key
static WaveChannelSubView::Type sType
static bool ShouldCaptureEvent(wxKeyEvent &event, SpectralData *pData)
static UIHandlePtr BrushHandleHitTest(std::weak_ptr< BrushHandle > &holder, const TrackPanelMouseState &st, const AudacityProject *pProject, const std::shared_ptr< SpectrumView > &pChannelView, const std::shared_ptr< SpectralData > &mpData)
static Settings & settings()
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
WaveTrackPopupMenuTable & GetWaveTrackMenuTable()
static const int colorSchemes
@ ColorGradientUnselected
@ ColorGradientTimeAndFrequencySelected
@ ColorGradientTimeSelected
static void PreComputeGradient()
static bool gradient_inited
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
static ChannelView & Get(Channel &channel)
virtual void DoSetMinimized(bool isMinimized)
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
auto FindChannel() -> std::shared_ptr< Subtype >
May return null.
float PositionToValue(float pp) const
Iterator begin(float nPositions) const
Dialog that shows the current PrefsPanel in a tabbed divider.
virtual void SavePreferredPage()=0
PrefsDialog(wxWindow *parent, AudacityProject *pProject, const TranslatableString &titlePrefix=XO("Preferences:"), PrefsPanel::Factories &factories=PrefsPanel::DefaultFactories())
virtual long GetPreferredPage()=0
std::vector< PrefsPanel::PrefsNode > Factories
A simple profiler to measure the average time lengths that a particular task/function takes....
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
Generates classes whose instances register items at construction.
static void SnapCenterOnce(SpectrumAnalyst &analyst, ViewInfo &viewInfo, const WaveChannel &wc, bool up)
Defines a selected portion of a project.
static const int UndefinedFrequency
void Grow(size_t len_, SpectrogramSettings &settings, double samplesPerPixel, double start)
void Populate(const SpectrogramSettings &settings, const WaveChannelInterval &clip, int copyBegin, int copyEnd, size_t numPixels, double pixelsPerSecond)
std::vector< float > freq
std::vector< sampleCount > where
std::vector< HopsAndBinsMap > dataHistory
static bool ProcessTracks(AudacityProject &project)
void SetBounds(float min, float max)
void GetBounds(const WaveChannel &wc, float &min, float &max) const
static SpectrogramBounds & Get(WaveTrack &track)
Get either the global default settings, or the track's own if previously created.
static SpectrogramSettings & Get(const WaveTrack &track)
Used for finding the peaks, for snapping to peaks.
AudacityProject * mpProject
SpectralDataSaver(SpectrumView &view)
~SpectralDataSaver() override
void Init(AudacityProject &project, bool clearAll) override
static void ForAll(AudacityProject &project, std::function< void(SpectrumView &view)> fn)
void DoSetMinimized(bool minimized) override
unsigned CaptureKey(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
bool IsSpectral() const override
void DoDraw(TrackPanelDrawingContext &context, const WaveChannel &channel, const WaveTrack::Interval *selectedClip, const wxRect &rect)
std::shared_ptr< SpectralData > mpSpectralData
std::weak_ptr< BrushHandle > mBrushHandle
unsigned KeyDown(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
std::shared_ptr< SpectralData > mpBackupSpectralData
const Type & SubViewType() const override
unsigned Char(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
std::shared_ptr< SpectralData > GetSpectralData()
SpectrumView(WaveChannelView &waveChannelView, const SpectrumView &src)=delete
std::shared_ptr< ChannelVRulerControls > DoGetVRulerControls() override
std::vector< UIHandlePtr > DetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override
void CopyToSubView(WaveChannelSubView *destSubView) const override
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
static TrackArtist * Get(TrackPanelDrawingContext &)
bool GetSelected() const
Selectedness is always the same for all channels of a group.
static TrackList & Get(AudacityProject &project)
virtual void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
Holds a msgid for the translation catalog; may also bind format arguments.
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
IteratorRange< IntervalIterator< WaveClipChannel > > Intervals()
std::shared_ptr< WaveChannel > FindWaveChannel()
static void DrawBoldBoundaries(TrackPanelDrawingContext &context, const WaveChannel &channel, const wxRect &rect)
std::pair< bool, std::vector< UIHandlePtr > > DoDetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool, const std::shared_ptr< WaveChannel > &wt)
std::weak_ptr< WaveChannelView > GetWaveChannelView() const
static bool ClipDetailsVisible(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect)
static WaveChannelView & GetFirst(WaveTrack &wt)
Get the view of the first channel.
std::vector< WaveChannelSubView::Type > GetDisplays() const
sampleCount GetVisibleSampleCount() const override
size_t GetChannelIndex() const
int GetRate() const override
double GetPlayStartTime() const override
double GetStretchRatio() const override
sampleCount TimeToSamples(double time) const override
This allows multiple clips to be a part of one WaveTrack.
A Track that contains audio waveform data.
virtual bool Read(const wxString &key, bool *value) const =0
Positions or offsets within audio files need a wide type.
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
AUDACITY_DLL_API void DrawBackgroundWithSelection(TrackPanelDrawingContext &context, const wxRect &rect, const Channel &channel, const wxBrush &selBrush, const wxBrush &unselBrush, bool useSelection=true, bool useBeatsAlternateColor=false)
Helper: draws background with selection rect.
AUDACITY_DLL_API void DrawClipFolded(wxDC &dc, const wxRect &rect)
AUDACITY_DLL_API void DrawClipEdges(wxDC &dc, const wxRect &clipRect, bool selected=false)
constexpr auto sampleRate
void DoNextPeakFrequency(AudacityProject &project, bool up)
static CommandHandlerObject & findCommandHandler(AudacityProject &project)
auto SpectralSelectionMenu()
PopupMenuTable::AttachedItem sAttachment
AColor::ColorGradientChoice ChooseColorSet(float bin0, float bin1, float selBinLo, float selBinCenter, float selBinHi, int dashCount, bool isSpectral)
static float findValue(const float *spectrum, float bin0, float bin1, unsigned nBins, bool autocorrelation, int gain, int range)
std::pair< sampleCount, sampleCount > GetSelectedSampleIndices(const SelectedRegion &selectedRegion, const WaveChannelInterval &clip, bool trackIsSelected)
void DrawClipSpectrum(TrackPanelDrawingContext &context, const WaveChannel &channel, const WaveChannelInterval &clip, const wxRect &rect, const std::shared_ptr< SpectralData > &mpSpectralData, bool selected)
AuthorizationHandler handler
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
__finl float_x4 __vecc sqrt(const float_x4 &a)
A convenient default parameter for class template Site.
static wxRect GetClipRect(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect, bool *outShowSamples=nullptr)
bool GetSpectrogram(const WaveChannelInterval &clip, const float *&spectrogram, SpectrogramSettings &spectrogramSettings, const sampleCount *&where, size_t numPixels, double t0, double pixelsPerSecond)
static WaveClipSpectrumCache & Get(const WaveChannelInterval &clip)
void OnNextLowerPeakFrequency(const CommandContext &context)
void OnToggleSpectralSelection(const CommandContext &context)
void OnNextHigherPeakFrequency(const CommandContext &context)
static SpectrogramSettingsHandler & Instance()
void InitUserData(void *pUserData) override
Called before the menu items are appended.