| 23 | namespace { |
| 24 | struct DropoutSubscription : ClientData::Base { |
| 25 | DropoutSubscription(AudacityProject &project) |
| 26 | { |
| 27 | mSubscription = ProjectAudioManager::Get(project).Subscribe( |
| 28 | [&project](const RecordingDropoutEvent &evt){ |
| 29 | // Make a track with labels for recording errors |
| 30 | auto &tracks = TrackList::Get( project ); |
| 31 | |
| 32 | /* i18n-hint: A name given to a track, appearing as its menu button. |
| 33 | The translation should be short or else it will not display well. |
| 34 | At most, about 11 Latin characters. |
| 35 | Dropout is a loss of a short sequence of audio sample data from the |
| 36 | recording */ |
| 37 | auto pTrack = LabelTrack::Create(tracks, tracks.MakeUniqueTrackName(_("Dropouts"))); |
| 38 | long counter = 1; |
| 39 | for (auto &interval : evt.intervals) |
| 40 | pTrack->AddLabel( |
| 41 | SelectedRegion{ interval.first, |
| 42 | interval.first + interval.second }, |
| 43 | wxString::Format(wxT("%ld"), counter++)); |
| 44 | |
| 45 | auto &history = ProjectHistory::Get( project ); |
| 46 | history.ModifyState( true ); // this might fail and throw |
| 47 | |
| 48 | // CallAfter so that we avoid any problems of yielding |
| 49 | // to the event loop while still inside the timer callback, |
| 50 | // entering StopStream() recursively |
| 51 | auto &window = GetProjectFrame( project ); |
| 52 | wxTheApp->CallAfter( [&window] { |
| 53 | ShowWarningDialog(&window, wxT("DropoutDetected"), XO("\ |
| 54 | Recorded audio was lost at the labeled locations. Possible causes:\n\ |
| 55 | \n\ |
| 56 | Other applications are competing with Audacity for processor time\n\ |
| 57 | \n\ |
| 58 | You are saving directly to a slow external storage device\n\ |
| 59 | " |
| 60 | ), |
| 61 | false, |
| 62 | XXO("Turn off dropout detection")); |
| 63 | }); |
| 64 | }); |
| 65 | } |
| 66 | Observer::Subscription mSubscription; |
| 67 | }; |
| 68 | } |
nothing calls this directly
no test coverage detected