Thread: [Audacity-devel] New features available
A free multi-track audio editor and recorder
Brought to you by:
aosiniao
From: Juhana S. <ko...@ni...> - 2003-04-28 15:50:48
|
Hello. I have implemented four more features. See below. Download file "http://www.funet.fi/~kouhia/myaudacity-src-1.1.3c.tar.gz" if you which to try them out before moving changes to CVS. 609b0eb6d9d52c059b983ca6294a126c myaudacity-src-1.1.3c.tar.gz Quick questions: Where users need the input/output device mixer toolbar? It should not be needed as one should calibrate levels once after a new gear is connected; hardware mutes could find use, though. Please tell me that you're not trying to achive a feature by wrong means! How about putting the track labels and the tracks to their own subwindows? The time and amp rulers would go inside the tracks subwindow, and both subwindows would have a common scrollbar. This would solve the wrong update of the time ruler (as fixed in my feature 4 but not accepted). When arranged this way, user could simply close the track label subwindow and have more room for the tracks. See below for new features and code changes. Best regards, Juhana ---*--- Feature 6: Added the play region which is played instead of the selection. When we play the selection, the selection info is given to the routine which plays the play region. (I also tested adding the play region data to ViewInfo structure, but selected simpler approach.) This feature is needed because we want play without any relation to the selection; say, we do not want loose the selection when we play somewhere else. We also want, at request, the play to be unrelated to the play-autoscrolling, but I have not implemented it. However, see the Feature 7 where it is done with a quick solution. ControlToolBar.h/public ToolBar void PlayPlayRegion(double t0, double t1); ControlToolBar.cpp void ControlToolBar::PlayPlayRegion(double t0, double t1) { if (gAudioIO->IsStreamActive()) return; mStop->Enable(); mRewind->Disable(); mRecord->Disable(); mFF->Disable(); mPause->Enable(); AudacityProject *p = GetActiveProject(); if (p) { TrackList *t = p->GetTracks(); double maxofmins,minofmaxs; // JS: clarified how the final play region is computed; if (t1 == t0) { // we play from t0 to end // move t0 to valid range if (t0 < 0) t0 = t->GetStartTime(); if (t0 > t->GetEndTime()) t0 = t->GetEndTime(); // always play to end t1 = t->GetEndTime(); } else { // always t0 < t1 right? // the set intersection between the play region and the valid range // maximum of lower bounds if (t0 < t->GetStartTime()) maxofmins = t->GetStartTime(); else maxofmins = t0; // minimum of upper bounds if (t1 > t->GetEndTime()) minofmaxs = t->GetEndTime(); else minofmaxs = t1; // we test if the intersection has no volume if (minofmaxs <= maxofmins) { // no volume; play nothing return; } else { t0 = maxofmins; t1 = minofmaxs; } } bool success = false; if (t1 > t0) { int token = gAudioIO->StartStream(t->GetWaveTrackArray(false), WaveTrackArray(), t->GetTimeTrack(), p->GetRate(), t0, t1); if (token != 0) { success = true; p->SetAudioIOToken(token); mBusyProject = p; } } if (!success) { SetPlay(false); SetStop(false); SetRecord(false); } } } void ControlToolBar::OnPlay(wxCommandEvent &evt) { AudacityProject *p = GetActiveProject(); if (p) { PlayPlayRegion(p->GetSel0(),p->GetSel1()); } } Project.h // TrackPanel callback methods virtual void TP_PlayPlayRegion(double t0, double t1); Project.cpp // TrackPanel callback method // JS: plays the given region void AudacityProject::TP_PlayPlayRegion(double t0, double t1) { ControlToolBar *toolbar = GetControlToolBar(); wxCommandEvent evt; int i,k; //If busy, stop playing, make sure everything is unpaused. if (gAudioIO->IsStreamActive()) { toolbar->SetPlay(false); //Pops toolbar->SetStop(true); //Pushes stop down toolbar->OnStop(evt); } // JS: slight sleep needed --- what would be better? for(i = 0; i < 1000000; i++) k = i; // JS: and then start playing toolbar->SetPlay(true); toolbar->SetStop(false); toolbar->PlayPlayRegion(t0,t1); } TrackPanel.h/class TrackPanelListener public: virtual void TP_PlayPlayRegion(double t0, double t1) = 0; Note: The sleep in TP_PlayPlayRegion is needed so that the concurrent audio engine have enough time to stop the previous play. Is that correct? (I'm checking if the AudioIO could be replaced with something better in this context.) ---*--- Feature 7: Play samples around the pointer when a button is pressed. The feature plays 1 second audio segment; that should be configurable. While playing is on, the play-autoscroll is disabled. This feature was requested because the playing was difficult when the drawing tool was used. We have a focus problems in the start. It would be nice if the whole project is in the focus at the start. Also we have a focus problem if we first play a selection by pressing the play button. Then the focus is lost. (Focus should be set in the enter and the leave notify callbacks, or?) The key is now the "delete" key. A mouse button with a modifier would have worked better for me, but because the mouse event handling is confusing to me, I could not implement it. I also wanted some other key than "delete" because "delete" is at the right side of the keyboard --- I would have used a key at the left side. TrackPanel.cpp TrackPanel::UpdatePrefs gPrefs->Read("/GUI/AutoScroll", &mViewInfo->bUpdateTrackIndicatorPref, true); mViewInfo->bUpdateTrackIndicator = mViewInfo->bUpdateTrackIndicatorPref; TrackPanel::OnTimer // Next, check to see if we were playing or recording // audio, but now Audio I/O is completely finished. // The main point of this is to properly push the state // and flush the tracks once we've completely finished // recording new state. if (p->GetAudioIOToken()>0 && !gAudioIO->IsAudioTokenActive(p->GetAudioIOToken())) { // JS: set bUpdateTrackIndicator to its original state; // JS: we changed it temporarily for non-scrolling play mViewInfo->bUpdateTrackIndicator = mViewInfo->bUpdateTrackIndicatorPref; if (gAudioIO->GetNumCaptureChannels() > 0) { TrackPanel::OnKeyEvent case WXK_DELETE: double ptrpos; // JS: this plays samples around the pointer location // How to get pointer location? We should have always valid // pointer location info. We should also find out what // track is under the pointer if we do not play the entire // system. ptrpos = PositionToTime(mMouseMostRecentX,mCapturedRect.x); // non-scrolling play mViewInfo->bUpdateTrackIndicator = false; mListener->TP_PlayPlayRegion(ptrpos-0.5,ptrpos+0.5); break; Project.cpp AudacityProject::AudacityProject gPrefs->Read("/GUI/AutoScroll", &mViewInfo.bUpdateTrackIndicatorPref, true); mViewInfo.bUpdateTrackIndicator = mViewInfo.bUpdateTrackIndicatorPref; ViewInfo.h bool bUpdateTrackIndicatorPref; ---*--- Feature 8: A click on the track label won't loose the existing selection. The ctrl+click will perform the "select all on the track" operation. (Should shift+click invert the selection? It does not.) The reason for this change is that it was too easy to loose the existing selection. Also, while we have the focus problems, clicking to the panel seems to be only safe way to get the focus without loosing the selection. See the Feature 7: drag a selection, play it from the play button, try play around the pointer. It won't work unless you obtain the focus by clicking on the label. If you click on the track, you loose the selection. Note: if this "select all on the track" is different from "select all" of edit menu, then how about adding the operation to the track menu? TrackPanel.cpp TrackPanel::HandleLabelClick (see bottom of the routine) // JS: "select all on the track" changed under the ctrl modifier // JS: because it was too easy to loose the selection; // JS: XXX the track menu should have this operation if (event.ControlDown()) { SelectNone(); mTracks->Select(t); mViewInfo->sel0 = t->GetOffset(); mViewInfo->sel1 = t->GetEndTime(); Refresh(false); MakeParentPushState(wxString::Format(_("Changed Selection Region"))); } Refresh(false); ---*--- Feature 9: This feature is something I'm particularly proud of. I cannot make edits without this feature anymore. This is an essential tool in editing, and I have no idea how people succeeds to make edits without it -- you tell me how! Press of ctrl+mousebutton1 plays the region between the pointer and the nearest selection edge (or cursor). There are four regions which can be played depending on where the pointer is located: (1) pointer to first edge, (2) first edge to pointer, (3) pointer to second edge, and (4) second edge to pointer. The advantages are that user may listen to what is left out of the selection and how the selection starts and ends. In many editors, user may listen only how the selection starts. If the selection is 10 minutes long, it takes 10 minutes to reach the end of the selection. In those editors I make selections from end to start: first I make a short selection in the end and then I drag the first edge to the start. How do you do it? (Even if one has marks helping in making the selection, the feature is needed, or?) If the zoom ratio is small (we are editing at sample level), then the feature could play some minimum length region. The final play region would then be a set intersection of the region where the pointer is located and the minimum length region. (Draw figure.) I have not needed the extended feature in Waver because I have a separate overview display where I can do operations if the main display has a small zoom ratio. TrackPanel.cpp TrackPanel::TrackSpecificMouseEvent // JS: play the region between the pointer and the nearest selection // JS: edge (or the cursor) if (event.ControlDown() && event.ButtonDown(1)) { double ptrpos,t0,t1; ptrpos = PositionToTime(event.m_x,mCapturedRect.x); // check region between pointer and the nearest selection edge if (fabs(ptrpos - mViewInfo->sel0) < fabs(ptrpos - mViewInfo->sel1)) { t0 = mViewInfo->sel0; t1 = ptrpos; } else { t0 = mViewInfo->sel1; t1 = ptrpos; } // play range t0 and t1 if (t0 < t1) { mListener->TP_PlayPlayRegion(t0,t1); } else { mListener->TP_PlayPlayRegion(t1,t0); } return; } switch (mListener->TP_GetCurrentTool()) { case selectTool: HandleSelect(event); Warning: the feature hides any ctrl+mousebutton1 operations done in the following routines: HandleSelect(event); HandleEnvelope(event); HandleSlide(event); HandleZoom(event); HandleDraw(event); Therefore, if you wish, you may move the above code to the start of HandleSelect() routine. ---*--- |
From: julian g. <jul...@ja...> - 2003-04-30 09:55:38
|
I can report that audacity 1.1.3 does not work correctly on this box. Sound is played, but there is random pitch change and regular noise. Audacity 1.0.0 works fine. The M700 uses the Maestro chipset, has anyone else had problems? Julian |
From: James C. <cr...@in...> - 2003-05-03 15:00:50
|
----- Original Message ----- From: Juhana Sadeharju <ko...@ni...> Subject: [Audacity-devel] New features available Hi Juhana, I'm having some trouble understanding exactly what some of your new features do. Could you confirm that Feature 4 is a bug fix rather than new functionality? The fix causes the ruler above the TrackLabel to be repainted correctly and this doesn't happen at the moment. If that's what it is I can't understand why we wouldn't accept it.... Could you describe what feature 6 does again, I didn't understand it. Do I use the keyboard to play the play region? Is there a new 'Replay' button to play the play region? > Where users need the input/output device mixer toolbar? > It should not be needed as one should calibrate levels > once after a new gear is connected; hardware mutes could > find use, though. Please tell me that you're not trying > to achive a feature by wrong means! Are you saying we don't need a volume control in Audacity?!?? We most certainly do need one. > How about putting the track labels and the tracks to their > own subwindows? [..snip..] When arranged this way, user > could simply close the track label subwindow and have > more room for the tracks. I too think the TrackLabel display needs to be optional. Are you thinking of a splitter window (so that they can share a scrollbar) rather than two whole independent windows. Would a menu item that simply switches on and off the TrackLabels be enough? Or a style where they individually slide out from the left when you hover over? Regards, James. |