Audacity  2.2.2
TranscriptionToolBar.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  TranscriptionToolBar.cpp
6 
7  Shane T. Mueller
8  Leland Lucius
9 
10 *******************************************************************//*******************************************************************/
16 
17 #include "../Audacity.h"
18 #include "TranscriptionToolBar.h"
19 
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include <wx/wxprec.h>
22 
23 #ifndef WX_PRECOMP
24 #include <wx/choice.h>
25 #include <wx/defs.h>
26 #include <wx/brush.h>
27 #include <wx/image.h>
28 #include <wx/intl.h>
29 #endif // WX_PRECOMP
30 
31 #include "../Envelope.h"
32 
33 #include "ControlToolBar.h"
34 #include "../AllThemeResources.h"
35 #include "../AudioIO.h"
36 #include "../Experimental.h"
37 #include "../ImageManipulation.h"
38 #include "../Project.h"
39 #include "../TimeTrack.h"
40 #include "../WaveTrack.h"
41 #include "../widgets/AButton.h"
42 #include "../widgets/ASlider.h"
43 
44 #ifdef EXPERIMENTAL_VOICE_DETECTION
45 #include "../VoiceKey.h"
46 #endif
47 
49 
53 
54 
55 BEGIN_EVENT_TABLE(TranscriptionToolBar, ToolBar)
56  EVT_CHAR(TranscriptionToolBar::OnKeyEvent)
57  EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, TranscriptionToolBar::OnCaptureKey)
58 
59  EVT_COMMAND_RANGE(TTB_PlaySpeed, TTB_PlaySpeed,
60  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnPlaySpeed)
61  EVT_SLIDER(TTB_PlaySpeedSlider, TranscriptionToolBar::OnSpeedSlider)
62 
63 #ifdef EXPERIMENTAL_VOICE_DETECTION
64  EVT_COMMAND_RANGE(TTB_StartOn, TTB_StartOn,
65  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnStartOn)
66  EVT_COMMAND_RANGE(TTB_StartOff, TTB_StartOff,
67  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnStartOff)
68  EVT_COMMAND_RANGE(TTB_EndOn, TTB_EndOn,
69  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnEndOn)
70  EVT_COMMAND_RANGE(TTB_EndOff, TTB_EndOff,
71  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnEndOff)
72  EVT_COMMAND_RANGE(TTB_SelectSound, TTB_SelectSound,
73  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnSelectSound)
74  EVT_COMMAND_RANGE(TTB_SelectSilence, TTB_SelectSilence,
75  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnSelectSilence)
76  EVT_COMMAND_RANGE(TTB_AutomateSelection, TTB_AutomateSelection,
77  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnAutomateSelection)
78  EVT_COMMAND_RANGE(TTB_MakeLabel, TTB_MakeLabel,
79  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnMakeLabel)
80  EVT_COMMAND_RANGE(TTB_Calibrate, TTB_Calibrate,
81  wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnCalibrate)
82  EVT_SLIDER(TTB_SensitivitySlider, TranscriptionToolBar::OnSensitivitySlider)
83 
84  EVT_CHOICE(TTB_KeyType, TranscriptionToolBar::SetKeyType)
85 #endif
87  ; //semicolon enforces proper automatic indenting in emacs.
88 
91 : ToolBar(TranscriptionBarID, _("Transcription"), wxT("Transcription"))
92 {
93  mPlaySpeed = 1.0 * 100.0;
94 #ifdef EXPERIMENTAL_VOICE_DETECTION
95  mVk = std::make_unique<VoiceKey>();
96 #endif
97 }
98 
100 {
101 }
102 
103 void TranscriptionToolBar::Create(wxWindow * parent)
104 {
105  ToolBar::Create(parent);
106 
107  mBackgroundBrush.SetColour(wxColour(204, 204, 204));
108  mBackgroundPen.SetColour(wxColour(204, 204, 204));
109 
110  mBackgroundHeight = 0;
111  mBackgroundWidth = 0;
112 
113 #ifdef EXPERIMENTAL_VOICE_DETECTION
114  mButtons[TTB_StartOn]->Disable();
115  mButtons[TTB_StartOff]->Disable();
116  mButtons[TTB_EndOn]->Disable();
117  mButtons[TTB_EndOff]->Disable();
118  mButtons[TTB_SelectSound]->Disable();
119  mButtons[TTB_SelectSilence]->Disable();
120  mButtons[TTB_Calibrate]->Enable();
121  mButtons[TTB_AutomateSelection]->Disable();
122  mButtons[TTB_MakeLabel]->Enable();
123 #endif
124 
125  //Old code...
126  //Process a dummy event to set up mPlaySpeed
127  //wxCommandEvent dummy;
128  //OnSpeedSlider(dummy);
129 
130  //JKC: Set speed this way is better, as we don't
131  //then stop Audio if it is playing, so we can be playing
132  //audio and open a second project.
133  mPlaySpeed = (mPlaySpeedSlider->Get()) * 100;
134 }
135 
140  TranscriptionToolBar *pBar,
141  teBmps eFore, teBmps eDisabled,
142  int id,
143  const wxChar *label)
144 {
145  AButton *&r = pBar->mButtons[id];
146 
147  r = ToolBar::MakeButton(pBar,
148  bmpRecoloredUpSmall, bmpRecoloredDownSmall, bmpRecoloredUpHiliteSmall,bmpRecoloredHiliteSmall,
149  eFore, eFore, eDisabled,
150  wxWindowID(id),
151  wxDefaultPosition,
152  false,
153  theTheme.ImageSize( bmpRecoloredUpSmall ));
154 
155  r->SetLabel(label);
156 // JKC: Unlike ControlToolBar, does not have a focus rect. Shouldn't it?
157 // r->SetFocusRect( r->GetRect().Deflate( 4, 4 ) );
158 
159  pBar->Add( r, 0, wxALIGN_CENTER );
160 
161  return r;
162 }
163 
165  teBmps eFore, teBmps eDisabled,
166  int id, unsigned altIdx)
167 {
169  bmpRecoloredUpSmall, bmpRecoloredDownSmall, bmpRecoloredUpHiliteSmall,bmpRecoloredHiliteSmall,
170  eFore, eFore, eDisabled,
171  theTheme.ImageSize( bmpRecoloredUpSmall ));
172 }
173 
175 {
176  SetBackgroundColour( theTheme.Colour( clrMedium ) );
177 // Very similar to code in ControlToolBar...
178 // Very similar to code in EditToolBar
180 
181  AddButton(this, bmpPlay, bmpPlayDisabled, TTB_PlaySpeed,
182  _("Play at selected speed"));
183  MakeAlternateImages(bmpLoop, bmpLoopDisabled, TTB_PlaySpeed, 1);
184  MakeAlternateImages(bmpCutPreview, bmpCutPreviewDisabled, TTB_PlaySpeed, 2);
186 
187  //Add a slider that controls the speed of playback.
188  const int SliderWidth=100;
190  TTB_PlaySpeedSlider,
191  _("Playback Speed"),
192  wxDefaultPosition,
193  wxSize(SliderWidth,25),
195  .Style( SPEED_SLIDER )
196  // 6 steps using page up/down, and 60 using arrow keys
197  .Line( 0.16667f )
198  .Page( 0.16667f )
199  );
200  mPlaySpeedSlider->Set(mPlaySpeed / 100.0);
201  mPlaySpeedSlider->SetLabel(_("Playback Speed"));
202  Add( mPlaySpeedSlider, 0, wxALIGN_CENTER );
203  mPlaySpeedSlider->Bind(wxEVT_SET_FOCUS,
205  this);
206  mPlaySpeedSlider->Bind(wxEVT_KILL_FOCUS,
208  this);
209 
210 #ifdef EXPERIMENTAL_VOICE_DETECTION
211 // If we need these strings translated, then search and replace
212 // TRANSLATBLE by _ and remove this #define.
213 #define TRANSLATABLE( x ) wxT( x )
214  AddButton(this, bmpTnStartOn, bmpTnStartOnDisabled, TTB_StartOn,
215  TRANSLATABLE("Adjust left selection to next onset"));
216  AddButton(this, bmpTnEndOn, bmpTnEndOnDisabled, TTB_EndOn,
217  TRANSLATABLE("Adjust right selection to previous offset"));
218  AddButton(this, bmpTnStartOff, bmpTnStartOffDisabled, TTB_StartOff,
219  TRANSLATABLE("Adjust left selection to next offset"));
220  AddButton(this, bmpTnEndOff, bmpTnEndOffDisabled, TTB_EndOff,
221  TRANSLATABLE("Adjust right selection to previous onset"));
222  AddButton(this, bmpTnSelectSound, bmpTnSelectSoundDisabled, TTB_SelectSound,
223  TRANSLATABLE("Select region of sound around cursor"));
224  AddButton(this, bmpTnSelectSilence, bmpTnSelectSilenceDisabled, TTB_SelectSilence,
225  TRANSLATABLE("Select region of silence around cursor"));
226  AddButton(this, bmpTnAutomateSelection, bmpTnAutomateSelectionDisabled, TTB_AutomateSelection,
227  TRANSLATABLE("Automatically make labels from words"));
228  AddButton(this, bmpTnMakeTag, bmpTnMakeTagDisabled, TTB_MakeLabel,
229  TRANSLATABLE("Add label at selection"));
230  AddButton(this, bmpTnCalibrate, bmpTnCalibrateDisabled, TTB_Calibrate,
231  TRANSLATABLE("Calibrate voicekey"));
232 
234  TTB_SensitivitySlider,
235  TRANSLATABLE("Adjust Sensitivity"),
236  wxDefaultPosition,
237  wxSize(SliderWidth,25),
238  SPEED_SLIDER);
239  mSensitivitySlider->Set(.5);
240  mSensitivitySlider->SetLabel(TRANSLATABLE("Sensitivity"));
241  Add( mSensitivitySlider, 0, wxALIGN_CENTER );
242 
243  wxString choices[] =
244  {
245  TRANSLATABLE("Energy"),
246  TRANSLATABLE("Sign Changes (Low Threshold)"),
247  TRANSLATABLE("Sign Changes (High Threshold)"),
248  TRANSLATABLE("Direction Changes (Low Threshold)"),
249  TRANSLATABLE("Direction Changes (High Threshold)")
250  };
251 
252  mKeyTypeChoice = safenew wxChoice(this, TTB_KeyType,
253  wxDefaultPosition,
254  wxDefaultSize,
255  5,
256  choices );
257  mKeyTypeChoice->SetName(TRANSLATABLE("Key type"));
258  mKeyTypeChoice->SetSelection(0);
259  Add( mKeyTypeChoice, 0, wxALIGN_CENTER );
260 #endif
261 
262  // Add a little space
263  Add(2, -1);
264 
265  UpdatePrefs();
266 }
267 
269 {
270 #ifdef EXPERIMENTAL_VOICE_DETECTION
272  if (!p) return;
273  // Is anything selected?
274  bool selection = false;
275  TrackListIterator iter(p->GetTracks());
276  for (Track *t = iter.First(); t; t = iter.Next())
277  if (t->GetSelected()) {
278  selection = true;
279  break;
280  }
281  selection &= (p->GetSel0() < p->GetSel1());
282 
283  mButtons[TTB_Calibrate]->SetEnabled(selection);
284 #endif
285 }
286 
288 {
290 
291  // Set label to pull in language change
292  SetLabel(_("Transcription"));
293 
294  // Give base class a chance
296 }
297 
299 {
300  // We could also mention the shift- and ctrl-modified versions in the
301  // tool tip... but it would get long
302 
303  static const struct Entry {
304  int tool;
305  wxString commandName;
306  wxString untranslatedLabel;
307  wxString commandName2;
308  wxString untranslatedLabel2;
309  } table[] = {
310  { TTB_PlaySpeed, wxT("PlayAtSpeed"), XO("Play-at-Speed"),
311  wxT("PlayAtSpeedLooped"), XO("Looped-Play-at-Speed")
312  },
313  };
314 
315  for (const auto &entry : table) {
316  TranslatedInternalString commands[] = {
317  { entry.commandName, wxGetTranslation(entry.untranslatedLabel) },
318  { entry.commandName2, wxGetTranslation(entry.untranslatedLabel2) },
319  };
320  ToolBar::SetButtonToolTip( *mButtons[entry.tool], commands, 2u );
321  }
322 
323 
324 #ifdef EXPERIMENTAL_VOICE_DETECTION
325  mButtons[TTB_StartOn]->SetToolTip(TRANSLATABLE("Left-to-On"));
326  mButtons[TTB_EndOn]->SetToolTip( TRANSLATABLE("Right-to-Off"));
327  mButtons[TTB_StartOff]->SetToolTip( TRANSLATABLE("Left-to-Off"));
328  mButtons[TTB_EndOff]->SetToolTip( TRANSLATABLE("Right-to-On"));
329  mButtons[TTB_SelectSound]->SetToolTip( TRANSLATABLE("Select-Sound"));
330  mButtons[TTB_SelectSilence]->SetToolTip( TRANSLATABLE("Select-Silence"));
331  mButtons[TTB_AutomateSelection]->SetToolTip( TRANSLATABLE("Make Labels"));
332  mButtons[TTB_MakeLabel]->SetToolTip( TRANSLATABLE("Add Label"));
333  mButtons[TTB_Calibrate]->SetToolTip( TRANSLATABLE("Calibrate"));
334 
335  mSensitivitySlider->SetToolTip(TRANSLATABLE("Sensitivity"));
336  mKeyTypeChoice->SetToolTip(TRANSLATABLE("Key type"));
337 #endif
338 }
339 
340 void TranscriptionToolBar::OnFocus(wxFocusEvent &event)
341 {
342  if (event.GetEventType() == wxEVT_KILL_FOCUS) {
344  }
345  else {
347  }
348 
349  Refresh(false);
350 
351  event.Skip();
352 }
353 
354 void TranscriptionToolBar::OnCaptureKey(wxCommandEvent &event)
355 {
356  wxKeyEvent *kevent = (wxKeyEvent *)event.GetEventObject();
357  int keyCode = kevent->GetKeyCode();
358 
359  // Pass LEFT/RIGHT/UP/DOWN/PAGEUP/PAGEDOWN through for input/output sliders
360  if (FindFocus() == mPlaySpeedSlider && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
361  || keyCode == WXK_UP || keyCode == WXK_DOWN
362  || keyCode == WXK_PAGEUP || keyCode == WXK_PAGEDOWN)) {
363  return;
364  }
365 
366  event.Skip();
367 
368  return;
369 }
370 
371 //This handles key-stroke events????
372 void TranscriptionToolBar::OnKeyEvent(wxKeyEvent & event)
373 {
374  if (event.ControlDown()) {
375  event.Skip();
376  return;
377  }
378 
379  if (event.GetKeyCode() == WXK_SPACE) {
380  if (gAudioIO->IsBusy()) {
381  /*Do Stuff Here*/
382  }
383  else {
384  /*Do other stuff Here*/
385  }
386  }
387 }
388 
389 
390 
391 //This changes the state of the various buttons
392 void TranscriptionToolBar::SetButton(bool down, AButton* button)
393 {
394  if (down) {
395  button->PushDown();
396  }
397  else {
398  button->PopUp();
399  }
400 }
401 
403  const WaveTrack *t, sampleCount *s0, sampleCount *slen)
404 {
405  // GetSamples attempts to translate the start and end selection markers into sample indices
406  // These selection numbers are doubles.
407 
409  if (!p) {
410  return;
411  }
412 
413  //First, get the current selection. It is part of the mViewInfo, which is
414  //part of the project
415 
416  double start = p->GetSel0();
417  double end = p->GetSel1();
418 
419  auto ss0 = sampleCount( (start - t->GetOffset()) * t->GetRate() );
420  auto ss1 = sampleCount( (end - t->GetOffset()) * t->GetRate() );
421 
422  if (start < t->GetOffset()) {
423  ss0 = 0;
424  }
425 
426 #if 0
427  //This adjusts the right samplecount to the maximum sample.
428  if (ss1 >= t->GetNumSamples()) {
429  ss1 = t->GetNumSamples();
430  }
431 #endif
432 
433  if (ss1 < ss0) {
434  ss1 = ss0;
435  }
436 
437  *s0 = ss0;
438  *slen = ss1 - ss0;
439 }
440 
441 // Come here from button clicks, or commands
442 void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
443 {
444  // Can't do anything without an active project
446  if (!p) {
447  return;
448  }
449 
450  // Create a TimeTrack if we haven't done so already
451  if (!mTimeTrack) {
453  if (!mTimeTrack) {
454  return;
455  }
456  }
457 
458  // Pop up the button
459  SetButton(false, mButtons[TTB_PlaySpeed]);
460 
461  // If IO is busy, abort immediately
462  if (gAudioIO->IsBusy()) {
464  }
465 
466  // Set the speed range
467  //mTimeTrack->SetRangeUpper((double)mPlaySpeed / 100.0);
468  //mTimeTrack->SetRangeLower((double)mPlaySpeed / 100.0);
469  mTimeTrack->GetEnvelope()->Flatten((double)mPlaySpeed / 100.0);
470 
471  // Get the current play region
472  double playRegionStart, playRegionEnd;
473  p->GetPlayRegion(&playRegionStart, &playRegionEnd);
474 
475  // Start playing
476  if (playRegionStart >= 0) {
477 // playRegionEnd = playRegionStart + (playRegionEnd-playRegionStart)* 100.0/mPlaySpeed;
479  options.playLooped = looped;
480  options.timeTrack = mTimeTrack.get();
481  ControlToolBar::PlayAppearance appearance =
486  (SelectedRegion(playRegionStart, playRegionEnd),
487  options,
489  appearance);
490  }
491 }
492 
493 // Come here from button clicks only
494 void TranscriptionToolBar::OnPlaySpeed(wxCommandEvent & WXUNUSED(event))
495 {
496  auto button = mButtons[TTB_PlaySpeed];
497 
498  // Let control have precedence over shift
499  const bool cutPreview = mButtons[TTB_PlaySpeed]->WasControlDown();
500  const bool looped = !cutPreview &&
501  button->WasShiftDown();
502  PlayAtSpeed(looped, cutPreview);
503 }
504 
505 void TranscriptionToolBar::OnSpeedSlider(wxCommandEvent& WXUNUSED(event))
506 {
507  mPlaySpeed = (mPlaySpeedSlider->Get()) * 100;
509 
510  // If IO is busy, abort immediately
511  // AWD: This is disabled to work around a hang on Linux when PulseAudio is
512  // used. If we figure that one out we can re-enable this code.
513  //if (gAudioIO->IsBusy()) {
514  // OnPlaySpeed(event);
515  //}
516 }
517 
518 #ifdef EXPERIMENTAL_VOICE_DETECTION
519 void TranscriptionToolBar::OnStartOn(wxCommandEvent & WXUNUSED(event))
520 {
521  //If IO is busy, abort immediately
522  if (gAudioIO->IsBusy()){
523  SetButton(false,mButtons[TTB_StartOn]);
524  return;
525  }
526 
527  mVk->AdjustThreshold(GetSensitivity());
529 
530  TrackList *tl = p->GetTracks();
532 
533  Track *t = iter.First(); //Make a track
534  if(t ) {
535  auto wt = static_cast<const WaveTrack*>(t);
536  sampleCount start, len;
537  GetSamples(wt, &start, &len);
538 
539  //Adjust length to end if selection is null
540  //if(len == 0)
541  //len = wt->GetSequence()->GetNumSamples()-start;
542 
543  auto newstart = mVk->OnForward(*wt, start, len);
544  double newpos = newstart.as_double() / wt->GetRate();
545 
546  p->SetSel0(newpos);
547  p->RedrawProject();
548 
549  SetButton(false, mButtons[TTB_StartOn]);
550  }
551 }
552 
553 void TranscriptionToolBar::OnStartOff(wxCommandEvent & WXUNUSED(event))
554 {
555  //If IO is busy, abort immediately
556  if (gAudioIO->IsBusy()){
557  SetButton(false,mButtons[TTB_StartOff]);
558  return;
559  }
560  mVk->AdjustThreshold(GetSensitivity());
562 
563  TrackList *tl = p->GetTracks();
565 
566  SetButton(false, mButtons[TTB_StartOff]);
567  Track *t = iter.First(); //Make a track
568  if(t) {
569  auto wt = static_cast<const WaveTrack*>(t);
570  sampleCount start, len;
571  GetSamples(wt, &start, &len);
572 
573  //Adjust length to end if selection is null
574  //if(len == 0)
575  //len = wt->GetSequence()->GetNumSamples()-start;
576 
577  auto newstart = mVk->OffForward(*wt, start, len);
578  double newpos = newstart.as_double() / wt->GetRate();
579 
580  p->SetSel0(newpos);
581  p->RedrawProject();
582 
583  SetButton(false, mButtons[TTB_StartOn]);
584  }
585 }
586 
587 void TranscriptionToolBar::OnEndOn(wxCommandEvent & WXUNUSED(event))
588 {
589 
590  //If IO is busy, abort immediately
591  if (gAudioIO->IsBusy()){
592  SetButton(false,mButtons[TTB_EndOn]);
593  return;
594  }
595 
596  mVk->AdjustThreshold(GetSensitivity());
598  TrackList *tl = p->GetTracks();
600 
601  Track *t = iter.First(); //Make a track
602  if(t) {
603  auto wt = static_cast<const WaveTrack*>(t);
604  sampleCount start, len;
605  GetSamples(wt, &start, &len);
606 
607  //Adjust length to end if selection is null
608  if(len == 0)
609  {
610  len = start;
611  start = 0;
612  }
613  auto newEnd = mVk->OnBackward(*wt, start + len, len);
614  double newpos = newEnd.as_double() / wt->GetRate();
615 
616  p->SetSel1(newpos);
617  p->RedrawProject();
618 
619  SetButton(false, mButtons[TTB_EndOn]);
620  }
621 }
622 
623 
624 
625 void TranscriptionToolBar::OnEndOff(wxCommandEvent & WXUNUSED(event))
626 {
627 
628  //If IO is busy, abort immediately
629  if (gAudioIO->IsBusy()){
630  SetButton(false,mButtons[TTB_EndOff]);
631  return;
632  }
633  mVk->AdjustThreshold(GetSensitivity());
635  TrackList *tl = p->GetTracks();
637 
638  Track *t = iter.First(); //Make a track
639  if(t) {
640  auto wt = static_cast<const WaveTrack*>(t);
641  sampleCount start, len;
642  GetSamples(wt, &start, &len);
643 
644  //Adjust length to end if selection is null
645  if(len == 0) {
646  len = start;
647  start = 0;
648  }
649  auto newEnd = mVk->OffBackward(*wt, start + len, len);
650  double newpos = newEnd.as_double() / wt->GetRate();
651 
652  p->SetSel1(newpos);
653  p->RedrawProject();
654 
655  SetButton(false, mButtons[TTB_EndOff]);
656  }
657 }
658 
659 
660 
661 void TranscriptionToolBar::OnSelectSound(wxCommandEvent & WXUNUSED(event))
662 {
663 
664  //If IO is busy, abort immediately
665  if (gAudioIO->IsBusy()){
666  SetButton(false,mButtons[TTB_SelectSound]);
667  return;
668  }
669 
670 
671  mVk->AdjustThreshold(GetSensitivity());
673 
674 
675  TrackList *tl = p->GetTracks();
677 
678  Track *t = iter.First(); //Make a track
679  if(t)
680  {
681  auto wt = static_cast<const WaveTrack*>(t);
682  sampleCount start, len;
683  GetSamples(wt, &start, &len);
684 
685  //Adjust length to end if selection is null
686  //if(len == 0)
687  //len = wt->GetSequence()->GetNumSamples()-start;
688 
689  double rate = wt->GetRate();
690  auto newstart = mVk->OffBackward(*wt, start, start);
691  auto newend =
692  mVk->OffForward(*wt, start + len, (int)(tl->GetEndTime() * rate));
693 
694  //reset the selection bounds.
695  p->SetSel0(newstart.as_double() / rate);
696  p->SetSel1(newend.as_double() / rate);
697  p->RedrawProject();
698 
699  }
700 
701  SetButton(false,mButtons[TTB_SelectSound]);
702 }
703 
704 void TranscriptionToolBar::OnSelectSilence(wxCommandEvent & WXUNUSED(event))
705 {
706 
707  //If IO is busy, abort immediately
708  if (gAudioIO->IsBusy()){
709  SetButton(false,mButtons[TTB_SelectSilence]);
710  return;
711  }
712 
713  mVk->AdjustThreshold(GetSensitivity());
715 
716 
717  TrackList *tl = p->GetTracks();
719 
720  Track *t = iter.First(); //Make a track
721  if(t)
722  {
723  auto wt = static_cast<const WaveTrack*>(t);
724  sampleCount start, len;
725  GetSamples(wt, &start, &len);
726 
727  //Adjust length to end if selection is null
728  //if(len == 0)
729  //len = wt->GetSequence()->GetNumSamples()-start;
730  double rate = wt->GetRate();
731  auto newstart = mVk->OnBackward(*wt, start, start);
732  auto newend =
733  mVk->OnForward(*wt, start + len, (int)(tl->GetEndTime() * rate));
734 
735  //reset the selection bounds.
736  p->SetSel0(newstart.as_double() / rate);
737  p->SetSel1(newend.as_double() / rate);
738  p->RedrawProject();
739 
740  }
741 
742  SetButton(false,mButtons[TTB_SelectSilence]);
743 
744 }
745 
746 
747 
748 void TranscriptionToolBar::OnCalibrate(wxCommandEvent & WXUNUSED(event))
749 {
750  //If IO is busy, abort immediately
751  if (gAudioIO->IsBusy()){
752  SetButton(false,mButtons[TTB_Calibrate]);
753  return;
754  }
755 
756 
758 
759  TrackList *tl = p->GetTracks();
761  Track *t = iter.First(); //Get a track
762 
763  if(t)
764  {
765  auto wt = static_cast<const WaveTrack*>(t);
766  sampleCount start, len;
767  GetSamples(wt, &start, &len);
768 
769  mVk->CalibrateNoise(*wt, start, len);
770  mVk->AdjustThreshold(3);
771 
772  mButtons[TTB_StartOn]->Enable();
773  mButtons[TTB_StartOff]->Enable();
774  mButtons[TTB_EndOn]->Enable();
775  mButtons[TTB_EndOff]->Enable();
776  //mThresholdSensitivity->Set(3);
777 
778  SetButton(false,mButtons[TTB_Calibrate]);
779  }
780 
781  mButtons[TTB_StartOn]->Enable();
782  mButtons[TTB_StartOff]->Enable();
783  mButtons[TTB_EndOn]->Enable();
784  mButtons[TTB_EndOff]->Enable();
785  mButtons[TTB_SelectSound]->Enable();
786  mButtons[TTB_SelectSilence]->Enable();
787  mButtons[TTB_AutomateSelection]->Enable();
788 
789  //Make the sensititivy slider set the sensitivity by processing an event.
790  wxCommandEvent dummy;
791  OnSensitivitySlider(dummy);
792 
793 }
794 
795 //This automates selection through a selected region,
796 //selecting its best guess for words and creating labels at those points.
797 
798 void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
799 {
800 
801 
802  //If IO is busy, abort immediately
803  if (gAudioIO->IsBusy())
804  {
805  SetButton(false,mButtons[TTB_EndOff]);
806  return;
807  }
808 
809  wxBusyCursor busy;
810 
811  mVk->AdjustThreshold(GetSensitivity());
813  TrackList *tl = p->GetTracks();
815 
816  Track *t = iter.First(); //Make a track
817  if(t)
818  {
819  auto wt = static_cast<const WaveTrack*>(t);
820  sampleCount start, len;
821  GetSamples(wt, &start, &len);
822 
823  //Adjust length to end if selection is null
824  if(len == 0)
825  {
826  len = start;
827  start = 0;
828  }
829  sampleCount lastlen = 0;
830  double newStartPos, newEndPos;
831 
832 
833  //This is the minumum word size in samples (.05 is 50 ms)
834  int minWordSize = (int)(wt->GetRate() * .05);
835 
836  //Continue until we have processed the entire
837  //region, or we are making no progress.
838  while(len > 0 && lastlen != len)
839  {
840 
841  lastlen = len;
842 
843  auto newStart = mVk->OnForward(*wt, start, len);
844 
845  //JKC: If no start found then don't add any labels.
846  if( newStart==start)
847  break;
848 
849  //Adjust len by the NEW start position
850  len -= (newStart - start);
851 
852  //Adjust len by the minimum word size
853  len -= minWordSize;
854 
855 
856 
857  //OK, now we have found a NEW starting point. A 'word' should be at least
858  //50 ms long, so jump ahead minWordSize
859 
860  auto newEnd =
861  mVk->OffForward(*wt, newStart + minWordSize, len);
862 
863  //If newEnd didn't move, we should give up, because
864  // there isn't another end before the end of the selection.
865  if(newEnd == (newStart + minWordSize))
866  break;
867 
868 
869  //Adjust len by the NEW word end
870  len -= (newEnd - newStart);
871 
872  //Calculate the start and end of the words, in seconds
873  newStartPos = newStart.as_double() / wt->GetRate();
874  newEndPos = newEnd.as_double() / wt->GetRate();
875 
876 
877  //Increment
878  start = newEnd;
879 
880  p->DoAddLabel(SelectedRegion(newStartPos, newEndPos));
881  p->RedrawProject();
882  }
883  SetButton(false, mButtons[TTB_AutomateSelection]);
884  }
885 }
886 
887 void TranscriptionToolBar::OnMakeLabel(wxCommandEvent & WXUNUSED(event))
888 {
890  SetButton(false, mButtons[TTB_MakeLabel]);
891  p->DoAddLabel(SelectedRegion(p->GetSel0(), p->GetSel1()));
892 }
893 
894 //This returns a double z-score between 0 and 10.
895 double TranscriptionToolBar::GetSensitivity()
896 {
897  return (double)mSensitivity;
898 }
899 
900 void TranscriptionToolBar::OnSensitivitySlider(wxCommandEvent & WXUNUSED(event))
901 {
902  mSensitivity = (mSensitivitySlider->Get());
903 }
904 
905 void TranscriptionToolBar::SetKeyType(wxCommandEvent & WXUNUSED(event))
906 {
907  int value = mKeyTypeChoice->GetSelection();
908 
909  //Only use one key type at a time.
910  switch(value)
911  {
912  case 0:
913  mVk->SetKeyType(true,0,0,0,0);
914  break;
915  case 1:
916  mVk->SetKeyType(0,true,0,0,0);
917  break;
918  case 2:
919  mVk->SetKeyType(0,0,true,0,0);
920  break;
921  case 3:
922  mVk->SetKeyType(0,0,0,true,0);
923  break;
924  case 4:
925  mVk->SetKeyType(0,0,0,0,true);
926  break;
927  }
928 
929 }
930 #endif
931 
933 {
935  mPlaySpeedSlider->Refresh();
936  wxCommandEvent e;
937  OnSpeedSlider(e);
938 }
939 
941 {
942  mButtons[TTB_PlaySpeed]->SetEnabled(enabled);
943 }
944 
945 void TranscriptionToolBar::SetPlaying(bool down, bool looped, bool cutPreview)
946 {
947  AButton *const button = mButtons[TTB_PlaySpeed];
948  if (down) {
949  button->SetAlternateIdx(cutPreview ? 2 : looped ? 1 : 0);
950  button->PushDown();
951  }
952  else {
953  button->SetAlternateIdx(0);
954  button->PopUp();
955  }
956 }
957 
959 {
960  if (adj < 0) {
961  mPlaySpeedSlider->Decrease(-adj);
962  }
963  else {
965  }
966  wxCommandEvent e;
967  OnSpeedSlider(e);
968 }
969 
void MakeButtonBackgroundsSmall()
Definition: ToolBar.cpp:727
void SetAlternateIdx(unsigned idx)
Definition: AButton.cpp:248
void RedrawProject(const bool bForceWaveTracks=false)
Definition: Project.cpp:1371
A list of TrackListNode items.
Definition: Track.h:618
void SetSel1(double)
Definition: Project.cpp:1404
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:209
AudioIOStartStreamOptions GetDefaultPlayOptions()
Definition: Project.cpp:1291
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:89
virtual void UpdatePrefs()
Definition: ToolBar.cpp:535
double GetSel0() const
Definition: Project.h:204
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:374
void PopUp()
Definition: AButton.cpp:525
static void CaptureKeyboard(wxWindow *handler)
Definition: Project.cpp:5954
void OnPlaySpeed(wxCommandEvent &event)
void SetSel0(double)
Definition: Project.cpp:1397
void EnableDisableButtons() override
float Get(bool convert=true)
Definition: ASlider.cpp:1567
void MakeAlternateImages(teBmps eFore, teBmps eDisabled, int id, unsigned altIdx)
double GetEndTime() const
Definition: Track.cpp:1418
double GetOffset() const override
Definition: WaveTrack.cpp:219
wxString label
Definition: Tags.cpp:727
void OnKeyEvent(wxKeyEvent &event)
#define SPEED_SLIDER
Definition: ASlider.h:47
void FollowModifierKeys()
Definition: AButton.cpp:258
double as_double() const
Definition: Types.h:88
void StopPlaying(bool stopStream=true)
EVT_COMMAND_RANGE(TTB_PlaySpeed, TTB_PlaySpeed, wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnPlaySpeed)
Methods for TranscriptionToolBar.
#define XO(s)
Definition: Internat.h:33
void SetButton(bool newstate, AButton *button)
void OnSpeedSlider(wxCommandEvent &event)
void PlayAtSpeed(bool looped, bool cutPreview)
int DoAddLabel(const SelectedRegion &region, bool preserveFocus=false)
Definition: Menus.cpp:8510
int teBmps
Definition: Theme.h:28
wxSize ImageSize(int iIndex)
Definition: Theme.cpp:1257
bool IsBusy()
Returns true if audio i/o is busy starting, stopping, playing, or recording.
Definition: AudioIO.cpp:2910
static AButton * MakeButton(wxWindow *parent, teBmps eUp, teBmps eDown, teBmps eHilite, teBmps eDownHi, teBmps eStandardUp, teBmps eStandardDown, teBmps eDisabled, wxWindowID id, wxPoint placement, bool processdownevents, wxSize size)
Definition: ToolBar.cpp:765
void Create(wxWindow *parent) override
#define safenew
Definition: Audacity.h:230
Options & Page(float p)
Definition: ASlider.h:268
void OnFocus(wxFocusEvent &event)
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
std::unique_ptr< TimeTrack > NewTimeTrack()
Definition: TimeTrack.cpp:35
Defines a selected portion of a project.
static AButton * AddButton(TranscriptionToolBar *pBar, teBmps eFore, teBmps eDisabled, int id, const wxChar *label)
struct holding stream options, including a pointer to the TimeTrack and AudioIOListener and whether t...
Definition: AudioIO.h:114
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
void SetEnabled(bool state)
Definition: AButton.h:98
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:101
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:611
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:438
bool WasControlDown()
Definition: AButton.cpp:490
void Set(float value)
Definition: ASlider.cpp:1572
void SetEnabled(bool enabled)
Options & Line(float l)
Definition: ASlider.h:267
std::unique_ptr< TimeTrack > mTimeTrack
An iterator for a TrackList.
Definition: Track.h:401
static void ReleaseKeyboard(wxWindow *handler)
Definition: Project.cpp:5965
static void MakeAlternateImages(AButton &button, int idx, teBmps eUp, teBmps eDown, teBmps eHilite, teBmps eDownHi, teBmps eStandardUp, teBmps eStandardDown, teBmps eDisabled, wxSize size)
Definition: ToolBar.cpp:798
void Disable()
Definition: AButton.cpp:502
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
bool ShowDialog(wxPoint pos=wxPoint(-1,-1))
Definition: ASlider.cpp:1587
AudioIO * gAudioIO
Definition: AudioIO.cpp:482
int PlayPlayRegion(const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode playMode, PlayAppearance appearance=PlayAppearance::Straight, bool backwards=false, bool playWhiteSpace=false)
ControlToolBar * GetControlToolBar()
Definition: Project.cpp:4996
void OnCaptureKey(wxCommandEvent &event)
ASlider is a custom slider, allowing for a slicker look and feel.
Definition: ASlider.h:243
void Enable()
Definition: AButton.cpp:495
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:308
void Increase(float steps)
Definition: ASlider.cpp:1577
void GetSamples(const WaveTrack *t, sampleCount *s0, sampleCount *slen)
wxColour & Colour(int iIndex)
Definition: Theme.cpp:1225
void PushDown()
Definition: AButton.cpp:517
END_EVENT_TABLE()
double GetRate() const
Definition: WaveTrack.cpp:398
double GetSel1() const
Definition: Project.h:205
TrackList * GetTracks()
Definition: Project.h:192
void GetPlayRegion(double *playRegionStart, double *playRegionEnd)
Definition: Project.cpp:5441
AButton * mButtons[TTBNumButtons]
void RegenerateTooltips() override
static void SetButtonToolTip(AButton &button, const TranslatedInternalString commands[], size_t nCommands)
Definition: ToolBar.cpp:823
void SetPlaying(bool down, bool looped, bool cutPreview)
Options & Style(int s)
Definition: ASlider.h:260
A kind of ToolBar used to help with analysing voice recordings.
TrackFactory * GetTrackFactory()
Definition: Project.cpp:1427
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed...
Definition: ToolBar.h:87
IMPLEMENT_CLASS(TranscriptionToolBar, ToolBar)
A wxButton with mouse-over behaviour.
Definition: AButton.h:28
void Decrease(float steps)
Definition: ASlider.cpp:1582