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 
316  for (const auto &entry : table) {
317  commands.clear();
318  commands.push_back( LocalizedCommandName(
319  wxGetTranslation(entry.untranslatedLabel), entry.commandName
320  ) );
321  commands.push_back( LocalizedCommandName(
322  wxGetTranslation(entry.untranslatedLabel2), entry.commandName2
323  ) );
324  ToolBar::SetButtonToolTip(*mButtons[entry.tool], commands);
325  }
326 
327 
328 #ifdef EXPERIMENTAL_VOICE_DETECTION
329  mButtons[TTB_StartOn]->SetToolTip(TRANSLATABLE("Left-to-On"));
330  mButtons[TTB_EndOn]->SetToolTip( TRANSLATABLE("Right-to-Off"));
331  mButtons[TTB_StartOff]->SetToolTip( TRANSLATABLE("Left-to-Off"));
332  mButtons[TTB_EndOff]->SetToolTip( TRANSLATABLE("Right-to-On"));
333  mButtons[TTB_SelectSound]->SetToolTip( TRANSLATABLE("Select-Sound"));
334  mButtons[TTB_SelectSilence]->SetToolTip( TRANSLATABLE("Select-Silence"));
335  mButtons[TTB_AutomateSelection]->SetToolTip( TRANSLATABLE("Make Labels"));
336  mButtons[TTB_MakeLabel]->SetToolTip( TRANSLATABLE("Add Label"));
337  mButtons[TTB_Calibrate]->SetToolTip( TRANSLATABLE("Calibrate"));
338 
339  mSensitivitySlider->SetToolTip(TRANSLATABLE("Sensitivity"));
340  mKeyTypeChoice->SetToolTip(TRANSLATABLE("Key type"));
341 #endif
342 }
343 
344 void TranscriptionToolBar::OnFocus(wxFocusEvent &event)
345 {
346  if (event.GetEventType() == wxEVT_KILL_FOCUS) {
348  }
349  else {
351  }
352 
353  Refresh(false);
354 
355  event.Skip();
356 }
357 
358 void TranscriptionToolBar::OnCaptureKey(wxCommandEvent &event)
359 {
360  wxKeyEvent *kevent = (wxKeyEvent *)event.GetEventObject();
361  int keyCode = kevent->GetKeyCode();
362 
363  // Pass LEFT/RIGHT/UP/DOWN/PAGEUP/PAGEDOWN through for input/output sliders
364  if (FindFocus() == mPlaySpeedSlider && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
365  || keyCode == WXK_UP || keyCode == WXK_DOWN
366  || keyCode == WXK_PAGEUP || keyCode == WXK_PAGEDOWN)) {
367  return;
368  }
369 
370  event.Skip();
371 
372  return;
373 }
374 
375 //This handles key-stroke events????
376 void TranscriptionToolBar::OnKeyEvent(wxKeyEvent & event)
377 {
378  if (event.ControlDown()) {
379  event.Skip();
380  return;
381  }
382 
383  if (event.GetKeyCode() == WXK_SPACE) {
384  if (gAudioIO->IsBusy()) {
385  /*Do Stuff Here*/
386  }
387  else {
388  /*Do other stuff Here*/
389  }
390  }
391 }
392 
393 
394 
395 //This changes the state of the various buttons
396 void TranscriptionToolBar::SetButton(bool down, AButton* button)
397 {
398  if (down) {
399  button->PushDown();
400  }
401  else {
402  button->PopUp();
403  }
404 }
405 
407  const WaveTrack *t, sampleCount *s0, sampleCount *slen)
408 {
409  // GetSamples attempts to translate the start and end selection markers into sample indices
410  // These selection numbers are doubles.
411 
413  if (!p) {
414  return;
415  }
416 
417  //First, get the current selection. It is part of the mViewInfo, which is
418  //part of the project
419 
420  double start = p->GetSel0();
421  double end = p->GetSel1();
422 
423  auto ss0 = sampleCount( (start - t->GetOffset()) * t->GetRate() );
424  auto ss1 = sampleCount( (end - t->GetOffset()) * t->GetRate() );
425 
426  if (start < t->GetOffset()) {
427  ss0 = 0;
428  }
429 
430 #if 0
431  //This adjusts the right samplecount to the maximum sample.
432  if (ss1 >= t->GetNumSamples()) {
433  ss1 = t->GetNumSamples();
434  }
435 #endif
436 
437  if (ss1 < ss0) {
438  ss1 = ss0;
439  }
440 
441  *s0 = ss0;
442  *slen = ss1 - ss0;
443 }
444 
445 // Come here from button clicks, or commands
446 void TranscriptionToolBar::PlayAtSpeed(bool looped, bool cutPreview)
447 {
448  // Can't do anything without an active project
450  if (!p) {
451  return;
452  }
453 
454  // Create a TimeTrack if we haven't done so already
455  if (!mTimeTrack) {
457  if (!mTimeTrack) {
458  return;
459  }
460  }
461 
462  // Pop up the button
463  SetButton(false, mButtons[TTB_PlaySpeed]);
464 
465  // If IO is busy, abort immediately
466  if (gAudioIO->IsBusy()) {
468  }
469 
470  // Set the speed range
471  //mTimeTrack->SetRangeUpper((double)mPlaySpeed / 100.0);
472  //mTimeTrack->SetRangeLower((double)mPlaySpeed / 100.0);
473  mTimeTrack->GetEnvelope()->Flatten((double)mPlaySpeed / 100.0);
474 
475  // Get the current play region
476  double playRegionStart, playRegionEnd;
477  p->GetPlayRegion(&playRegionStart, &playRegionEnd);
478 
479  // Start playing
480  if (playRegionStart >= 0) {
481 // playRegionEnd = playRegionStart + (playRegionEnd-playRegionStart)* 100.0/mPlaySpeed;
483  options.playLooped = looped;
484  options.timeTrack = mTimeTrack.get();
485  ControlToolBar::PlayAppearance appearance =
490  (SelectedRegion(playRegionStart, playRegionEnd),
491  options,
493  appearance);
494  }
495 }
496 
497 // Come here from button clicks only
498 void TranscriptionToolBar::OnPlaySpeed(wxCommandEvent & WXUNUSED(event))
499 {
500  auto button = mButtons[TTB_PlaySpeed];
501 
502  // Let control have precedence over shift
503  const bool cutPreview = mButtons[TTB_PlaySpeed]->WasControlDown();
504  const bool looped = !cutPreview &&
505  button->WasShiftDown();
506  PlayAtSpeed(looped, cutPreview);
507 }
508 
509 void TranscriptionToolBar::OnSpeedSlider(wxCommandEvent& WXUNUSED(event))
510 {
511  mPlaySpeed = (mPlaySpeedSlider->Get()) * 100;
513 
514  // If IO is busy, abort immediately
515  // AWD: This is disabled to work around a hang on Linux when PulseAudio is
516  // used. If we figure that one out we can re-enable this code.
517  //if (gAudioIO->IsBusy()) {
518  // OnPlaySpeed(event);
519  //}
520 }
521 
522 #ifdef EXPERIMENTAL_VOICE_DETECTION
523 void TranscriptionToolBar::OnStartOn(wxCommandEvent & WXUNUSED(event))
524 {
525  //If IO is busy, abort immediately
526  if (gAudioIO->IsBusy()){
527  SetButton(false,mButtons[TTB_StartOn]);
528  return;
529  }
530 
531  mVk->AdjustThreshold(GetSensitivity());
533 
534  TrackList *tl = p->GetTracks();
536 
537  Track *t = iter.First(); //Make a track
538  if(t ) {
539  auto wt = static_cast<const WaveTrack*>(t);
540  sampleCount start, len;
541  GetSamples(wt, &start, &len);
542 
543  //Adjust length to end if selection is null
544  //if(len == 0)
545  //len = wt->GetSequence()->GetNumSamples()-start;
546 
547  auto newstart = mVk->OnForward(*wt, start, len);
548  double newpos = newstart.as_double() / wt->GetRate();
549 
550  p->SetSel0(newpos);
551  p->RedrawProject();
552 
553  SetButton(false, mButtons[TTB_StartOn]);
554  }
555 }
556 
557 void TranscriptionToolBar::OnStartOff(wxCommandEvent & WXUNUSED(event))
558 {
559  //If IO is busy, abort immediately
560  if (gAudioIO->IsBusy()){
561  SetButton(false,mButtons[TTB_StartOff]);
562  return;
563  }
564  mVk->AdjustThreshold(GetSensitivity());
566 
567  TrackList *tl = p->GetTracks();
569 
570  SetButton(false, mButtons[TTB_StartOff]);
571  Track *t = iter.First(); //Make a track
572  if(t) {
573  auto wt = static_cast<const WaveTrack*>(t);
574  sampleCount start, len;
575  GetSamples(wt, &start, &len);
576 
577  //Adjust length to end if selection is null
578  //if(len == 0)
579  //len = wt->GetSequence()->GetNumSamples()-start;
580 
581  auto newstart = mVk->OffForward(*wt, start, len);
582  double newpos = newstart.as_double() / wt->GetRate();
583 
584  p->SetSel0(newpos);
585  p->RedrawProject();
586 
587  SetButton(false, mButtons[TTB_StartOn]);
588  }
589 }
590 
591 void TranscriptionToolBar::OnEndOn(wxCommandEvent & WXUNUSED(event))
592 {
593 
594  //If IO is busy, abort immediately
595  if (gAudioIO->IsBusy()){
596  SetButton(false,mButtons[TTB_EndOn]);
597  return;
598  }
599 
600  mVk->AdjustThreshold(GetSensitivity());
602  TrackList *tl = p->GetTracks();
604 
605  Track *t = iter.First(); //Make a track
606  if(t) {
607  auto wt = static_cast<const WaveTrack*>(t);
608  sampleCount start, len;
609  GetSamples(wt, &start, &len);
610 
611  //Adjust length to end if selection is null
612  if(len == 0)
613  {
614  len = start;
615  start = 0;
616  }
617  auto newEnd = mVk->OnBackward(*wt, start + len, len);
618  double newpos = newEnd.as_double() / wt->GetRate();
619 
620  p->SetSel1(newpos);
621  p->RedrawProject();
622 
623  SetButton(false, mButtons[TTB_EndOn]);
624  }
625 }
626 
627 
628 
629 void TranscriptionToolBar::OnEndOff(wxCommandEvent & WXUNUSED(event))
630 {
631 
632  //If IO is busy, abort immediately
633  if (gAudioIO->IsBusy()){
634  SetButton(false,mButtons[TTB_EndOff]);
635  return;
636  }
637  mVk->AdjustThreshold(GetSensitivity());
639  TrackList *tl = p->GetTracks();
641 
642  Track *t = iter.First(); //Make a track
643  if(t) {
644  auto wt = static_cast<const WaveTrack*>(t);
645  sampleCount start, len;
646  GetSamples(wt, &start, &len);
647 
648  //Adjust length to end if selection is null
649  if(len == 0) {
650  len = start;
651  start = 0;
652  }
653  auto newEnd = mVk->OffBackward(*wt, start + len, len);
654  double newpos = newEnd.as_double() / wt->GetRate();
655 
656  p->SetSel1(newpos);
657  p->RedrawProject();
658 
659  SetButton(false, mButtons[TTB_EndOff]);
660  }
661 }
662 
663 
664 
665 void TranscriptionToolBar::OnSelectSound(wxCommandEvent & WXUNUSED(event))
666 {
667 
668  //If IO is busy, abort immediately
669  if (gAudioIO->IsBusy()){
670  SetButton(false,mButtons[TTB_SelectSound]);
671  return;
672  }
673 
674 
675  mVk->AdjustThreshold(GetSensitivity());
677 
678 
679  TrackList *tl = p->GetTracks();
681 
682  Track *t = iter.First(); //Make a track
683  if(t)
684  {
685  auto wt = static_cast<const WaveTrack*>(t);
686  sampleCount start, len;
687  GetSamples(wt, &start, &len);
688 
689  //Adjust length to end if selection is null
690  //if(len == 0)
691  //len = wt->GetSequence()->GetNumSamples()-start;
692 
693  double rate = wt->GetRate();
694  auto newstart = mVk->OffBackward(*wt, start, start);
695  auto newend =
696  mVk->OffForward(*wt, start + len, (int)(tl->GetEndTime() * rate));
697 
698  //reset the selection bounds.
699  p->SetSel0(newstart.as_double() / rate);
700  p->SetSel1(newend.as_double() / rate);
701  p->RedrawProject();
702 
703  }
704 
705  SetButton(false,mButtons[TTB_SelectSound]);
706 }
707 
708 void TranscriptionToolBar::OnSelectSilence(wxCommandEvent & WXUNUSED(event))
709 {
710 
711  //If IO is busy, abort immediately
712  if (gAudioIO->IsBusy()){
713  SetButton(false,mButtons[TTB_SelectSilence]);
714  return;
715  }
716 
717  mVk->AdjustThreshold(GetSensitivity());
719 
720 
721  TrackList *tl = p->GetTracks();
723 
724  Track *t = iter.First(); //Make a track
725  if(t)
726  {
727  auto wt = static_cast<const WaveTrack*>(t);
728  sampleCount start, len;
729  GetSamples(wt, &start, &len);
730 
731  //Adjust length to end if selection is null
732  //if(len == 0)
733  //len = wt->GetSequence()->GetNumSamples()-start;
734  double rate = wt->GetRate();
735  auto newstart = mVk->OnBackward(*wt, start, start);
736  auto newend =
737  mVk->OnForward(*wt, start + len, (int)(tl->GetEndTime() * rate));
738 
739  //reset the selection bounds.
740  p->SetSel0(newstart.as_double() / rate);
741  p->SetSel1(newend.as_double() / rate);
742  p->RedrawProject();
743 
744  }
745 
746  SetButton(false,mButtons[TTB_SelectSilence]);
747 
748 }
749 
750 
751 
752 void TranscriptionToolBar::OnCalibrate(wxCommandEvent & WXUNUSED(event))
753 {
754  //If IO is busy, abort immediately
755  if (gAudioIO->IsBusy()){
756  SetButton(false,mButtons[TTB_Calibrate]);
757  return;
758  }
759 
760 
762 
763  TrackList *tl = p->GetTracks();
765  Track *t = iter.First(); //Get a track
766 
767  if(t)
768  {
769  auto wt = static_cast<const WaveTrack*>(t);
770  sampleCount start, len;
771  GetSamples(wt, &start, &len);
772 
773  mVk->CalibrateNoise(*wt, start, len);
774  mVk->AdjustThreshold(3);
775 
776  mButtons[TTB_StartOn]->Enable();
777  mButtons[TTB_StartOff]->Enable();
778  mButtons[TTB_EndOn]->Enable();
779  mButtons[TTB_EndOff]->Enable();
780  //mThresholdSensitivity->Set(3);
781 
782  SetButton(false,mButtons[TTB_Calibrate]);
783  }
784 
785  mButtons[TTB_StartOn]->Enable();
786  mButtons[TTB_StartOff]->Enable();
787  mButtons[TTB_EndOn]->Enable();
788  mButtons[TTB_EndOff]->Enable();
789  mButtons[TTB_SelectSound]->Enable();
790  mButtons[TTB_SelectSilence]->Enable();
791  mButtons[TTB_AutomateSelection]->Enable();
792 
793  //Make the sensititivy slider set the sensitivity by processing an event.
794  wxCommandEvent dummy;
795  OnSensitivitySlider(dummy);
796 
797 }
798 
799 //This automates selection through a selected region,
800 //selecting its best guess for words and creating labels at those points.
801 
802 void TranscriptionToolBar::OnAutomateSelection(wxCommandEvent & WXUNUSED(event))
803 {
804 
805 
806  //If IO is busy, abort immediately
807  if (gAudioIO->IsBusy())
808  {
809  SetButton(false,mButtons[TTB_EndOff]);
810  return;
811  }
812 
813  wxBusyCursor busy;
814 
815  mVk->AdjustThreshold(GetSensitivity());
817  TrackList *tl = p->GetTracks();
819 
820  Track *t = iter.First(); //Make a track
821  if(t)
822  {
823  auto wt = static_cast<const WaveTrack*>(t);
824  sampleCount start, len;
825  GetSamples(wt, &start, &len);
826 
827  //Adjust length to end if selection is null
828  if(len == 0)
829  {
830  len = start;
831  start = 0;
832  }
833  sampleCount lastlen = 0;
834  double newStartPos, newEndPos;
835 
836 
837  //This is the minumum word size in samples (.05 is 50 ms)
838  int minWordSize = (int)(wt->GetRate() * .05);
839 
840  //Continue until we have processed the entire
841  //region, or we are making no progress.
842  while(len > 0 && lastlen != len)
843  {
844 
845  lastlen = len;
846 
847  auto newStart = mVk->OnForward(*wt, start, len);
848 
849  //JKC: If no start found then don't add any labels.
850  if( newStart==start)
851  break;
852 
853  //Adjust len by the NEW start position
854  len -= (newStart - start);
855 
856  //Adjust len by the minimum word size
857  len -= minWordSize;
858 
859 
860 
861  //OK, now we have found a NEW starting point. A 'word' should be at least
862  //50 ms long, so jump ahead minWordSize
863 
864  auto newEnd =
865  mVk->OffForward(*wt, newStart + minWordSize, len);
866 
867  //If newEnd didn't move, we should give up, because
868  // there isn't another end before the end of the selection.
869  if(newEnd == (newStart + minWordSize))
870  break;
871 
872 
873  //Adjust len by the NEW word end
874  len -= (newEnd - newStart);
875 
876  //Calculate the start and end of the words, in seconds
877  newStartPos = newStart.as_double() / wt->GetRate();
878  newEndPos = newEnd.as_double() / wt->GetRate();
879 
880 
881  //Increment
882  start = newEnd;
883 
884  p->DoAddLabel(SelectedRegion(newStartPos, newEndPos));
885  p->RedrawProject();
886  }
887  SetButton(false, mButtons[TTB_AutomateSelection]);
888  }
889 }
890 
891 void TranscriptionToolBar::OnMakeLabel(wxCommandEvent & WXUNUSED(event))
892 {
894  SetButton(false, mButtons[TTB_MakeLabel]);
895  p->DoAddLabel(SelectedRegion(p->GetSel0(), p->GetSel1()));
896 }
897 
898 //This returns a double z-score between 0 and 10.
899 double TranscriptionToolBar::GetSensitivity()
900 {
901  return (double)mSensitivity;
902 }
903 
904 void TranscriptionToolBar::OnSensitivitySlider(wxCommandEvent & WXUNUSED(event))
905 {
906  mSensitivity = (mSensitivitySlider->Get());
907 }
908 
909 void TranscriptionToolBar::SetKeyType(wxCommandEvent & WXUNUSED(event))
910 {
911  int value = mKeyTypeChoice->GetSelection();
912 
913  //Only use one key type at a time.
914  switch(value)
915  {
916  case 0:
917  mVk->SetKeyType(true,0,0,0,0);
918  break;
919  case 1:
920  mVk->SetKeyType(0,true,0,0,0);
921  break;
922  case 2:
923  mVk->SetKeyType(0,0,true,0,0);
924  break;
925  case 3:
926  mVk->SetKeyType(0,0,0,true,0);
927  break;
928  case 4:
929  mVk->SetKeyType(0,0,0,0,true);
930  break;
931  }
932 
933 }
934 #endif
935 
937 {
939  mPlaySpeedSlider->Refresh();
940  wxCommandEvent e;
941  OnSpeedSlider(e);
942 }
943 
945 {
946  mButtons[TTB_PlaySpeed]->SetEnabled(enabled);
947 }
948 
949 void TranscriptionToolBar::SetPlaying(bool down, bool looped, bool cutPreview)
950 {
951  AButton *const button = mButtons[TTB_PlaySpeed];
952  if (down) {
953  button->SetAlternateIdx(cutPreview ? 2 : looped ? 1 : 0);
954  button->PushDown();
955  }
956  else {
957  button->SetAlternateIdx(0);
958  button->PopUp();
959  }
960 }
961 
963 {
964  if (adj < 0) {
965  mPlaySpeedSlider->Decrease(-adj);
966  }
967  else {
969  }
970  wxCommandEvent e;
971  OnSpeedSlider(e);
972 }
973 
void MakeButtonBackgroundsSmall()
Definition: ToolBar.cpp:732
void SetAlternateIdx(unsigned idx)
Definition: AButton.cpp:248
void RedrawProject(const bool bForceWaveTracks=false)
Definition: Project.cpp:1347
A list of TrackListNode items.
Definition: Track.h:611
void SetSel1(double)
Definition: Project.cpp:1380
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:209
AudioIOStartStreamOptions GetDefaultPlayOptions()
Definition: Project.cpp:1267
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:88
virtual void UpdatePrefs()
Definition: ToolBar.cpp:540
double GetSel0() const
Definition: Project.h:186
void PopUp()
Definition: AButton.cpp:525
static void CaptureKeyboard(wxWindow *handler)
Definition: Project.cpp:5780
void OnPlaySpeed(wxCommandEvent &event)
void SetSel0(double)
Definition: Project.cpp:1373
void EnableDisableButtons() override
float Get(bool convert=true)
Definition: ASlider.cpp:1700
void MakeAlternateImages(teBmps eFore, teBmps eDisabled, int id, unsigned altIdx)
static void SetButtonToolTip(AButton &button, const LocalizedCommandNameVector &commands)
Definition: ToolBar.cpp:828
double GetEndTime() const
Definition: Track.cpp:1409
double GetOffset() const override
Definition: WaveTrack.cpp:219
wxString label
Definition: Tags.cpp:727
void OnKeyEvent(wxKeyEvent &event)
#define SPEED_SLIDER
Definition: ASlider.h:46
void FollowModifierKeys()
Definition: AButton.cpp:258
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:30
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:8147
int teBmps
Definition: Theme.h:28
wxSize ImageSize(int iIndex)
Definition: Theme.cpp:1240
bool IsBusy()
Returns true if audio i/o is busy starting, stopping, playing, or recording.
Definition: AudioIO.cpp:2891
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:770
void Create(wxWindow *parent) override
#define safenew
Definition: Audacity.h:223
Options & Page(float p)
Definition: ASlider.h:267
void OnFocus(wxFocusEvent &event)
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:158
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:97
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:94
std::vector< LocalizedCommandName > LocalizedCommandNameVector
Definition: ToolBar.h:160
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:616
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:443
bool WasControlDown()
Definition: AButton.cpp:490
void Set(float value)
Definition: ASlider.cpp:1705
void SetEnabled(bool enabled)
Options & Line(float l)
Definition: ASlider.h:266
std::unique_ptr< TimeTrack > mTimeTrack
An iterator for a TrackList.
Definition: Track.h:394
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
static void ReleaseKeyboard(wxWindow *handler)
Definition: Project.cpp:5791
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:803
void Disable()
Definition: AButton.cpp:502
bool ShowDialog(wxPoint pos=wxPoint(-1,-1))
Definition: ASlider.cpp:1720
AudioIO * gAudioIO
Definition: AudioIO.cpp:481
int PlayPlayRegion(const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode playMode, PlayAppearance appearance=PlayAppearance::Straight, bool backwards=false, bool playWhiteSpace=false)
void SetLabel(const wxString &label)
Definition: ToolBar.cpp:379
ControlToolBar * GetControlToolBar()
Definition: Project.cpp:4803
void OnCaptureKey(wxCommandEvent &event)
ASlider is a custom slider, allowing for a slicker look and feel.
Definition: ASlider.h:242
void Enable()
Definition: AButton.cpp:495
AUDACITY_DLL_API AudacityProject * GetActiveProject()
Definition: Project.cpp:300
std::pair< wxString, const wxChar * > LocalizedCommandName
Definition: ToolBar.h:159
void Increase(float steps)
Definition: ASlider.cpp:1710
void GetSamples(const WaveTrack *t, sampleCount *s0, sampleCount *slen)
wxColour & Colour(int iIndex)
Definition: Theme.cpp:1208
void PushDown()
Definition: AButton.cpp:517
END_EVENT_TABLE()
double GetRate() const
Definition: WaveTrack.cpp:424
double GetSel1() const
Definition: Project.h:187
TrackList * GetTracks()
Definition: Project.h:174
void GetPlayRegion(double *playRegionStart, double *playRegionEnd)
Definition: Project.cpp:5267
AButton * mButtons[TTBNumButtons]
void RegenerateTooltips() override
void SetPlaying(bool down, bool looped, bool cutPreview)
Options & Style(int s)
Definition: ASlider.h:259
A kind of ToolBar used to help with analysing voice recordings.
TrackFactory * GetTrackFactory()
Definition: Project.cpp:1403
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:27
void Decrease(float steps)
Definition: ASlider.cpp:1715