/// <summary> /// Dump current sound into an Audio object. /// </summary> /// <param name="name">The name that display on panes.</param> /// <param name="saveName">The intended save name.</param> /// <param name="matchScriptID">The corresponding script id for the current track.</param> /// <returns>An Audio object with all fields set up.</returns> public static Audio DumpAudio(string name, string saveName, int length, int matchScriptID) { // get length from file if length is not specified if (length == -1) { length = GetAudioLength(saveName); } var audio = new Audio { Name = name, SaveName = saveName, LengthMillis = length, Length = ConvertMillisToTime(length), MatchScriptID = matchScriptID, Type = GetAudioType(saveName) }; return audio; }
private void MapShapesWithAudio(PowerPointSlide slide) { var relativeSlideId = GetRelativeSlideIndex(slide.ID); XmlParser xmlParser; string searchRule = string.Format("^({0}|{1})", SpeechShapePrefixOld, SpeechShapePrefix); var shapes = slide.GetShapesWithMediaType(PpMediaType.ppMediaTypeSound, new Regex(searchRule)); if (shapes.Count == 0) { return; } try { xmlParser = new XmlParser(string.Format(_tempShapAudioXmlFormat, relativeSlideId + 1)); } catch (ArgumentException) { // xml does not exist, means this page is either a new page or // created dues to pasting. For either case we do nothing return; } // iterate through all shapes, skip audios that are not generated speech foreach (var shape in shapes) { var audio = new Audio(); // detect audio type switch (shape.MediaFormat.AudioSamplingRate) { case Audio.GeneratedSamplingRate: audio.Type = Audio.AudioType.Auto; break; case Audio.RecordedSamplingRate: audio.Type = Audio.AudioType.Record; break; default: MessageBox.Show(TextCollection.RecorderUnrecognizeAudio); break; } // derive matched id from shape name var temp = shape.Name.Split(new[] { ' ' }); audio.MatchScriptID = Int32.Parse(temp[2]); // get corresponding audio audio.Name = shape.Name; audio.SaveName = _tempFullPath + xmlParser.GetCorrespondingAudio(audio.Name); audio.Length = AudioHelper.GetAudioLengthString(audio.SaveName); audio.LengthMillis = AudioHelper.GetAudioLength(audio.SaveName); // maintain a sorted audio list // Note: here relativeID == slide.Index - 1 if (audio.MatchScriptID >= _audioList[relativeSlideId].Count) { _audioList[relativeSlideId].Add(audio); } else { _audioList[relativeSlideId].Insert(audio.MatchScriptID, audio); } // match id > total script count -> script does not exsit if (audio.MatchScriptID >= _scriptList[relativeSlideId].Count) { audio.MatchScriptID = -1; } } }
public void RecButtonIdleHandler() { // close unfinished session ResetSession(); // check input device, abort if no input device connected if (!NInputDeviceExists()) { MessageBox.Show(TextCollection.RecorderNoInputDeviceMsg, TextCollection.RecorderNoInputDeviceMsgBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // UI settings ResetRecorder(); statusLabel.Text = TextCollection.RecorderRecordingStatusLabel; statusLabel.Visible = true; recButton.Image = Properties.Resources.Pause; // disable control of playing playButton.Enabled = false; // enable stop button stopButton.Enabled = true; // disable control of both lists recDisplay.Enabled = false; scriptDisplay.Enabled = false; // clear the undo buffer _undoAudioBuffer = null; // track the on going script index if not in slide show mode if (_inShowControlBox == null || _inShowControlBox.GetCurrentStatus() == InShowControl.ButtonStatus.Idle) { // if there's a corresponding script if (scriptDisplay.SelectedIndices.Count > 0) { _replaceScriptIndex = scriptDisplay.SelectedIndices[0]; } else { _replaceScriptIndex = -1; } _replaceScriptSlide = PowerPointCurrentPresentationInfo.CurrentSlide; } // change the status to recording status _recButtonStatus = RecorderStatus.Recording; // new record, clip counter and total length should be reset _recordClipCnt = 0; _recordTotalLength = 0; // construct new save name var tempSaveName = String.Format(_tempWaveFileNameFormat, _recordClipCnt); // start recording NStartRecordAudio(tempSaveName, 11025, 16, 1, true); // start the timer _timerCnt = 0; _timer = new System.Threading.Timer(TimerEvent, null, 0, 1000); }
public void StopButtonRecordingHandler(int scriptIndex, PowerPointSlide currentSlide, bool buffered) { // enable the control of play button playButton.Enabled = true; // change rec button status, rec button text, update status label // and stop timer _recButtonStatus = RecorderStatus.Idle; recButton.Image = Properties.Resources.Record; statusLabel.Text = TextCollection.RecorderReadyStatusLabel; ResetTimer(); // get current playback, can be null if there's no matched audio var currentPlayback = GetPlaybackFromList(scriptIndex, currentSlide.ID); try { // stop recording in the first play to reduce redundant recording NStopRecordAudio(); // adjust the stop time difference between timer-stop and recording-stop _recordTotalLength += NGetRecordLengthMillis(); timerLabel.Text = AudioHelper.ConvertMillisToTime(_recordTotalLength); // recorder resources clean up NCleanup(); // ask if the user wants to do the replacement var result = DialogResult.Yes; // prompt to the user only when escaping the slide show while recording if (_inShowControlBox != null && _inShowControlBox.GetCurrentStatus() == InShowControl.ButtonStatus.Estop) { if (currentPlayback == null) { result = MessageBox.Show(TextCollection.RecorderSaveRecordMsg, TextCollection.RecorderSaveRecordMsgBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); } else { result = MessageBox.Show( string.Format(TextCollection.RecorderReplaceRecordMsgFormat, currentPlayback.Name), TextCollection.RecorderReplaceRecordMsgBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); } } if (result == DialogResult.No) { // user does not want to save the file, delete all the temp files DeleteTempAudioFiles(); } else { // user confirms the recording, save the file and replace the record string saveName; string displayName; Audio newRec; var relativeSlideId = GetRelativeSlideIndex(currentSlide.ID); // map the script index with record index // here a simple iteration will find: // 1. the replacement position if a record exists; // 2. an insertion position if a record needs to be added // specially, index == -1 means the record needs to be appended var recordIndex = -1; if (scriptIndex == -1) { if (recDisplay.SelectedItems.Count > 0) { recordIndex = recDisplay.SelectedIndices[0]; } } else { for (int i = 0; i < _audioList[relativeSlideId].Count; i++) { var audio = _audioList[relativeSlideId][i]; if (audio.MatchScriptID >= scriptIndex) { recordIndex = i; break; } } } // if current playback != null -> there's a corresponding record for the // script, we can do the replacement; if (currentPlayback != null) { saveName = currentPlayback.SaveName.Replace(".wav", " rec.wav"); displayName = currentPlayback.Name; var matchId = currentPlayback.MatchScriptID; if (scriptIndex == -1) { matchId = -1; } newRec = AudioHelper.DumpAudio(displayName, saveName, _recordTotalLength, matchId); // note down the old record and replace the record list _undoAudioBuffer = _audioList[relativeSlideId][recordIndex]; _audioList[relativeSlideId][recordIndex] = newRec; // update the item in display // check status of in show control box to: // 1. reduce unnecessary update (won't see the display lists while slide show) // 2. current slide == null during slide show, use in show box status to guard // null ptr exception. if (_inShowControlBox == null || _inShowControlBox.GetCurrentStatus() != InShowControl.ButtonStatus.Rec && relativeSlideId == GetRelativeSlideIndex(PowerPointCurrentPresentationInfo.CurrentSlide.ID)) { UpdateRecordList(recordIndex, displayName, newRec.Length); } } else // if current playback == null -> there's NO corresponding record for the // script, we need to construct the new record and insert it to a proper // position { var saveNameSuffix = " " + scriptIndex + " rec.wav"; saveName = _tempFullPath + String.Format(SaveNameFormat, relativeSlideId) + saveNameSuffix; // the display name -> which script it corresponds to displayName = String.Format(SpeechShapeFormat, scriptIndex); newRec = AudioHelper.DumpAudio(displayName, saveName, _recordTotalLength, scriptIndex); // insert the new audio if (recordIndex == -1) { _audioList[relativeSlideId].Add(newRec); // update record index, will be used in highlighting recordIndex = _audioList[relativeSlideId].Count - 1; } else { _audioList[relativeSlideId].Insert(recordIndex, newRec); } // update the whole record display list if not in slide show mode if (_inShowControlBox == null || _inShowControlBox.GetCurrentStatus() != InShowControl.ButtonStatus.Rec && relativeSlideId == GetRelativeSlideIndex(PowerPointCurrentPresentationInfo.CurrentSlide.ID)) { UpdateRecordList(relativeSlideId); // highlight the latest added record recDisplay.Items[recordIndex].Selected = true; } } // save current sound -> rename the temp file to the correct save name NMergeAudios(_tempFullPath, "temp", saveName); // update the script list if not in slide show mode if (scriptIndex != -1 && (_inShowControlBox == null || _inShowControlBox.GetCurrentStatus() != InShowControl.ButtonStatus.Rec && relativeSlideId == GetRelativeSlideIndex(PowerPointCurrentPresentationInfo.CurrentSlide.ID))) { UpdateScriptList(scriptIndex, null, ScriptStatus.Recorded); } // check if we need to buffer the audio or embed the audio if (!buffered) { newRec.EmbedOnSlide(currentSlide, scriptIndex); if (!Globals.ThisAddIn.Ribbon.RemoveAudioEnabled) { Globals.ThisAddIn.Ribbon.RemoveAudioEnabled = true; Globals.ThisAddIn.Ribbon.RefreshRibbonControl("RemoveAudioButton"); } } else { while (AudioBuffer.Count < currentSlide.Index) { AudioBuffer.Add(new List<Tuple<Audio, int>>()); } AudioBuffer[currentSlide.Index - 1].Add(new Tuple<Audio, int>(newRec, scriptIndex)); } } } catch (Exception e) { ErrorDialogWrapper.ShowDialog("Record cannot be saved\n", "Error when saving the file", e); throw; } finally // do the following UI re-setup { // enable control of both lists recDisplay.Enabled = true; scriptDisplay.Enabled = true; // disable stop button stopButton.Enabled = false; } }
private void RefreshAudioList(PowerPointSlide slide, string[] names) { var relativeSlideId = GetRelativeSlideIndex(slide.ID); while (relativeSlideId >= _audioList.Count) { _audioList.Add(new List<Audio>()); } _audioList[relativeSlideId].Clear(); // if audio names have not been given, retrieve from files. if (names == null) { MapShapesWithAudio(slide); } else { // construct audio object and put into audio collection for (int i = 0; i < names.Length; i++) { string saveName = names[i]; string name = String.Format(SpeechShapeFormat, i); var audio = new Audio(name, saveName, i); _audioList[relativeSlideId].Add(audio); } } }