switch to Spectogram display by code

Audio software developers forum.
Forum rules
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: switch to Spectogram display by code

Post by Edgar » Tue Mar 12, 2013 4:28 am

jerome42 wrote: For the moment I have no inspiration on how to go on
I see what's happening to cause our approach to fail and I see how to resolve the problem. It's going to take quite a bit of code and there's absolutely no way to do it cleanly in an object-oriented way (at least that I can see).

The code is failing here:

Code: Select all

wxASSERT(mPopupMenuTarget
            && mPopupMenuTarget->GetKind() == Track::Wave);
in void TrackPanel::OnSetDisplay(wxCommandEvent & event) because OnSetDisplay is only expecting to be called from the pop-up menu in the track info panel; in our case we are calling it from elsewhere and mPopupMenuTarget is NULL.

The way I see it the best way to resolve this is to create a new public TrackPanel function:

Code: Select all

virtual void OnSetDisplayToSpectrum (WaveTrack * pWaveTrack);

Code: Select all

void TrackPanel::OnSetDisplayToSpectrum(WaveTrack * pWaveTrack)
I've got most of the code written (patch attached) and I know how to derive the missing pointer value; it will involve dereferencing from one or both of these:

Code: Select all

   TrackFactory   *mFactory;
   TrackList      *mTracks;      // the complete list of all tracks
members of class Effect; it will most likely be the first track of mTracks but you might have to dig it out of mFactory.

The place where you will need to do this work is here:

Code: Select all

bool EffectClickRemoval::PromptUser()
{
   wxWindow * baseWindow = GetParent();//new public method of Effect class
   AudacityProject * currentProject = (AudacityProject *)baseWindow;
   TrackPanel * trackPanel = currentProject->GetTrackPanel();
   WaveTrack * waveTrack = NULL;
   //WaveTrack * waveTrack = ???; //you will need to figure out how to finish this line!
   trackPanel->OnSetDisplayToSpectrum(waveTrack);

   ClickRemovalDialog dlog(this, mParent);
In ClickRemoval.cpp.

Right now if you call the function with waveTrack equal to NULL you will just get a message box; if you wish to test out my working code you can do so by removing the comments between "begin test" and "end test":

Code: Select all

void TrackPanel::OnSetDisplay(wxCommandEvent & event)
{
   int id = event.GetId();
   wxASSERT(id >= OnWaveformID && id <= OnPitchID);
   wxASSERT(mPopupMenuTarget
            && mPopupMenuTarget->GetKind() == Track::Wave);

   id -= OnWaveformID;
   WaveTrack *wt = (WaveTrack *) mPopupMenuTarget;

   //begin test
//      OnSetDisplayToSpectrum(wt);
//      return;
   // end test
in TrackPanel.cpp then use the drop-down menu as normal - try switching to Pitch, in fact it will switch to Spectrogram. I left in a couple of superfluous wxMessageBox calls which you would need to remove for production code.

I am going to be out of town on business for the next 14 days with limited access to this forum and email and probably no access to the source code so don't be bummed out if you reply and see nothing from me for a while!
Attachments
spectrum1.patch
(3.8 KiB) Downloaded 117 times

Gale Andrews
Quality Assurance
Posts: 41761
Joined: Fri Jul 27, 2007 12:02 am
Operating System: Windows 10

Re: switch to Spectogram display by code

Post by Gale Andrews » Tue Mar 12, 2013 5:22 am

jerome42 wrote:if Thinklabs did write code we could use here, it's not available as their modification is not open source as far as I could see.
It was Vaughan's (Audacity developer) code. Even if it was Thinklabs code, the modification would have to be open source under our GPL licence.

I think most or all of it is here
http://tinyurl.com/cmvnypl .


Gale
________________________________________FOR INSTANT HELP: (Click on Link below)
* * * * * Tips * * * * * Tutorials * * * * * Quick Start Guide * * * * * Audacity Manual

jerome42
Posts: 60
Joined: Fri Jan 11, 2013 9:20 am
Operating System: Please select

Re: switch to Spectogram display by code

Post by jerome42 » Tue Mar 12, 2013 9:38 am

Edgar wrote:I am going to be out of town on business for the next 14 days with limited access to this forum and email and probably no access to the source code so don't be bummed out if you reply and see nothing from me for a while!
Don't worry Edgar, you and Gale gave me enough new stuff (.patch, audacity-cvs) to dive into and keep me busy at least for the next 14 days!

jerome42
Posts: 60
Joined: Fri Jan 11, 2013 9:20 am
Operating System: Please select

Re: switch to Spectogram display by code

Post by jerome42 » Tue Mar 12, 2013 7:39 pm

jerome42 wrote:Don't worry Edgar, you and Gale gave me enough new stuff (.patch, audacity-cvs) to dive into and keep me busy at least for the next 14 days!
Hope you don't mind Edgar, that I did things a little on my own way today. I preferred to postpone being involved in dealing with .patch and /or audacity-cvs stuff as long as possible. Therefor I again concentrated on your and my code and found that mPopupMenuTarget was of type Track. And wandering a while through the Audacity code with that in mind, I could collect those few lines which got the switching job done:

Code: Select all

{
   AudacityProject *p = GetActiveProject(); 
   Track * pTrack;
   pTrack = p->GetFirstVisible();
   TrackPanel * trackPanel = p->GetTrackPanel();    
   trackPanel->mPopupMenuTarget = pTrack;

   wxCommandEvent eventCustom( wxID_ANY );
 //  int iSpectrumID = 2023;                          // TrackPanel::OnSpectrumID = 2023
   int iSpectrumID = trackPanel->Get_SpectrumID();    // new trackpanel entry to replace the above line,
                                                      // as the actual value of OnSpectrumID changes quite often.
   eventCustom.SetId(iSpectrumID);
   trackPanel->OnSetDisplay(eventCustom);             // this call gets the switching to frequency display done.
 }
The only problem left, is that I didn't succeed in getting the switching done by sending an event. But I do not care anymore about that!
Thanks very much for triggering and guiding me to get my problem solved. At least I think it is solved, but you never know :)
Kind regards, jerome42

jerome42
Posts: 60
Joined: Fri Jan 11, 2013 9:20 am
Operating System: Please select

Re: switch to Spectogram display by code

Post by jerome42 » Tue Apr 09, 2013 10:37 am

Hello Edgar,
Our last contact was about a month ago already. Hope everything has gone well with you?
In the meantime I spend days in searching through the Audicity source code, with an efficiency of one day searching to find just one codeline or one function that would solve my needs of that moment.
Anyhow the handling of custom events has now been solved and a new effect menu entrance 'Click Removal (automatic beta)...' has been added.
This effects menu entry shows the audio file in Spectrum mode and scrolls automatically to the right in steps of 90% of the window width.
In this mode it shows the cracks which I want to detect automatically, but before diving into that detection bussiness I would like to be able to toggle between Spectrum and Waveform display by just one single keystroke.
And there I found a problem which looks realy hard:
Such toggling command is not foreseen in the Preferences Keyboard 'Key Bindings' list, so I would like to add that command to the 'Key Bindings' list.
However I can't find the source of that list.
In CommandManager::GetAllCommandNames() there is a mCommandList item which contains all command names, but I can't find the place where this mCommandList is filled and where a new item can be added. It looks like its source is a DLL somewhere.
Maybe you have an idea? or would you know somenbody who can throw some light on this?
Kind regards,
Jerome42

Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: switch to Spectogram display by code

Post by Edgar » Tue Apr 09, 2013 4:49 pm

jerome42 wrote: Such toggling command is not foreseen in the Preferences Keyboard 'Key Bindings' list, so I would like to add that command to the 'Key Bindings' list.
However I can't find the source of that list.
The easiest way I have found to resolve this is to add an additional menu entry and assign it a keystroke; adding a menu item automatically creates a new entry in the binding list; you may add it to an existing menu, submenu or to a menu you create for this purpose. Here are a couple of examples of functions I have added for my own personal use (see menu.cpp):

Code: Select all

c->AddItem(wxT("ExportThenExit"), _("Export then exit..."), FN(OnExportThenExit), AudioIONotBusyFlag | WaveTracksExistFlag, AudioIONotBusyFlag | WaveTracksExistFlag);
c->AddItem(wxT("SelectBetweenLabels"), _("Select Between Labels"), FN(OnSelectBetweenLabels), wxT("Alt+Shift+L"));
c->AddItem(wxT("OnRemoveSelectedLabels"), _("Remove Selected Labels"), FN(OnRemoveSelectedLabels), wxT("Ctrl+Shift+H"), AudioIONotBusyFlag | LabelsSelectedFlag | IsNotSyncLockedFlag, AudioIONotBusyFlag | LabelsSelectedFlag | IsNotSyncLockedFlag);
note that the first instance has no default key binding, the second instance has no flags and the final instance has both; if you have trouble figuring out the flags let me know and I might be able to help you with it but for me it was simply a case of trial and error (lots and lots of error <grin>!) and looking at the examples from other menu entries.

jerome42
Posts: 60
Joined: Fri Jan 11, 2013 9:20 am
Operating System: Please select

Re: switch to Spectogram display by code

Post by jerome42 » Tue Apr 09, 2013 8:02 pm

Here are a couple of examples of functions I have added for my own personal use (see menu.cpp)
My goodness, Edgar, sóóó simple..., I wouldn't have found this in days, expected it to be much more complicated!
Thanks a lot, also for your quick respons.
Maybe you have also some code on the shelve for detecting cracks ? :)
Regards, Jerome42

Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: switch to Spectogram display by code

Post by Edgar » Tue Apr 09, 2013 8:47 pm

jerome42 wrote: Maybe you have also some code on the shelve for detecting cracks ? :)
Probably not, it would depend on how similar the "cracks" are. Have a look at the Noise Removal code. If you get stuck, post a verbal definition for "cracks" and a short audio sample (zipped wave file) which has at least three "cracks" scattered amongst good audio and someone might be able to help.

jerome42
Posts: 60
Joined: Fri Jan 11, 2013 9:20 am
Operating System: Please select

Re: switch to Spectogram display by code

Post by jerome42 » Thu May 02, 2013 9:16 am

Hello Steve, Edgar, Gale and all other occasional readers - if any-,

This is a sort of progress report.
Switching between Wave and Spectrum display and vv by code, isn't a problem anymore.
Under preferences::keyboard::view I added a command 'Spectrum or Wave toggle' which is activated by pressing the keyboard 'X' - very handy, at least for me.
So from my point of view this forum thread could be closed or even deleted.

As promised earlier, my next and main subject is: the automatic click removal.
It took some time to learn all in's and out's of the Audacity source code and the design philosofy behind it, as it is the result of more than ten years development by ten's of very talented programmers.
A first beta of an automatic click removal tryal is now finished and ready for use, but not for general use as it is still too beta.
I didn't follow the general layout that is available for Effect' s, because that layout forces an Effect to work invisible in the background with a progress dialog for the user. The user is only allowed to watch the progress or to cancel the whole operation.

I wanted to be able to see on screen what happens, to pause the process for watching more closely what happened and to resume or cancel as required.
So the processing is done per screen display: first one sees some detected crack(s), and when those cracks are processed, one sees the result for a few moments. Then the display is scrolled further to right for about 80% of the display-width and the procedure repeats. A small dialogue window on top of the screen - different from the progress dialogue of course - contains the buttons for user input to control the procedure.
It works, but very, very slowly with an efficiency of 1/10 ( 10 minutes to process 1 minute) due to the frequent screen refreshing.

Other than by Craig DeForest's wave-clipping approach, cracks are repaired by applying the waveform extrapolation code of Dominic Mazzoni. This code is very advanced and mathematically interesting and gives the repaired waveform a very natural look.
Nevertheless: now it is possible to apply it automatically to a reasonable length of (very) impaired audio, it becomes clear that it doesn't match the requirements of the human ear: the sharp sounding clicks having many high harmonics are gone indeed but they seem to be replaced by a very nasty sounding gurgling, having only low frequency content. That is very surprising as the repaired waveform looks very natural!

So my next approach will be to apply Dominic Mazzoni's extrapolation code in the frequency domain to each individual frequency around a crack.
I am afraid it will take some time before you hear again from me...

kind regards,
jerome42

Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: switch to Spectogram display by code

Post by Edgar » Thu May 02, 2013 4:42 pm

I understand your desire to trade the behind-the-scenes philosophy currently employed by Effects for something that you can watch and interrupt as needed. Good luck with your effort!

Post Reply