public DataProvider GetSingleWavClipDataProvider() { if (mWavClips.Count == 1) { WavClip theChosenOne = mWavClips[0]; return(theChosenOne.DataProvider); } return(null); }
//private void checkPcmFormat(Stream stream) //{ // if (!Presentation.MediaDataManager.EnforceSinglePCMFormat) // { // return; // } // uint dataLength; // AudioLibPCMFormat format = AudioLibPCMFormat.RiffHeaderParse(stream, out dataLength); // //if (dataLength <= 0) // //{ // // dataLength = (uint)(stream.Length - stream.Position); // //} // if (!format.IsCompatibleWith(PCMFormat.Data)) // { // throw new exception.InvalidDataFormatException( // String.Format("RIFF WAV file has incompatible PCM format")); // } //} public override void AppendPcmData(DataProvider fileDataProvider) { if (fileDataProvider.MimeType != DataProviderFactory.AUDIO_WAV_MIME_TYPE) { throw new exception.OperationNotValidException( "The mime type of the given DataProvider is not WAV !"); } WavClip newSingleWavClip = new WavClip(fileDataProvider); mWavClips.Add(newSingleWavClip); checkPcmFormat(newSingleWavClip); NotifyAudioDataInserted(this, AudioDuration, newSingleWavClip.MediaDuration); }
public void InsertPcmData(WavAudioMediaData mediaData, Time insertPoint, Time duration) { Time movingInsertPoint = insertPoint.Copy(); Time remainingAvailableDuration = duration.Copy(); foreach (WavClip wavClip in mediaData.mWavClips) { Time wavClipDur = wavClip.Duration; if (wavClipDur.IsLessThan(remainingAvailableDuration) || wavClipDur.IsEqualTo(remainingAvailableDuration)) { InsertPcmData(wavClip.Copy(), movingInsertPoint, wavClipDur); movingInsertPoint.Add(wavClipDur); remainingAvailableDuration.Substract(wavClipDur); if (remainingAvailableDuration.IsLessThan(Time.Zero) || remainingAvailableDuration.IsEqualTo(Time.Zero)) { break; } } else { WavClip smallerClip = wavClip.Copy(); smallerClip.ClipEnd = smallerClip.ClipBegin.Copy(); smallerClip.ClipEnd.Add(remainingAvailableDuration); InsertPcmData(smallerClip, movingInsertPoint, remainingAvailableDuration); //Stream stream = wavClip.OpenPcmInputStream(Time.Zero, // new Time(wavClip.ClipBegin.AsTimeSpan + remainingAvailableDuration.AsTimeSpan)); //try //{ // InsertPcmData(stream, movingInsertPoint, remainingAvailableDuration); //} //finally //{ // stream.Close(); //} break; } } }
/// <summary> /// Forces the PCM data to be stored in a single <see cref="DataProvider"/>. /// </summary> /// <remarks> /// This effectively copies the data, /// since the <see cref="DataProvider"/>(s) previously used to store the PCM data are left untouched /// </remarks> public DataProvider ForceSingleDataProvider(bool reuseSingleWavClip, string fileNamePrefix) { if (mWavClips.Count == 0) { return(null); } if (reuseSingleWavClip && mWavClips.Count == 1) { WavClip theChosenOne = mWavClips[0]; if (theChosenOne.ClipBegin.IsEqualTo(Time.Zero) && theChosenOne.ClipEnd.IsEqualTo(theChosenOne.MediaDuration)) { if (!String.IsNullOrEmpty(fileNamePrefix)) { ((FileDataProvider)theChosenOne.DataProvider).Rename(fileNamePrefix); } return(theChosenOne.DataProvider); } } WavClip newSingleClip; DataProvider dataProvider = null; Stream audioData = OpenPcmInputStream(); try { dataProvider = CreateDataProviderFromRawPCMStream(audioData, null, fileNamePrefix); newSingleClip = new WavClip(dataProvider); } finally { audioData.Close(); } mWavClips.Clear(); mWavClips.Add(newSingleClip); return(dataProvider); }
public override void AppendPcmData(DataProvider fileDataProvider, Time clipBegin, Time clipEnd) { if (fileDataProvider.MimeType != DataProviderFactory.AUDIO_WAV_MIME_TYPE) { throw new exception.OperationNotValidException( "The mime type of the given DataProvider is not WAV !"); } WavClip newSingleWavClip = new WavClip(fileDataProvider); if (clipBegin != null) { newSingleWavClip.ClipBegin = clipBegin.Copy(); } if (clipEnd != null) { newSingleWavClip.ClipEnd = clipEnd.Copy(); } mWavClips.Add(newSingleWavClip); checkPcmFormat(newSingleWavClip); NotifyAudioDataInserted(this, AudioDuration, newSingleWavClip.Duration); //ClipEnd.GetDifference(newSingleWavClip.ClipBegin)); }
private void checkPcmFormat(WavClip clip) { if (!Presentation.MediaDataManager.EnforceSinglePCMFormat) { return; } if (!clip.PcmFormat.IsCompatibleWith(PCMFormat.Data)) { throw new exception.InvalidDataFormatException( String.Format("RIFF WAV file has incompatible PCM format")); } ////Stream stream = newSingleWavClip.OpenPcmInputStream(); // Skips the RIFF header ! //Stream stream = clip.DataProvider.OpenInputStream(); //try //{ // checkPcmFormat(stream); //} //finally //{ // stream.Close(); //} }
/// <summary> /// Removes the audio between given clip begin and end points /// </summary> /// <param name="clipBegin">The given clip begin point</param> /// <param name="clipEnd">The given clip end point</param> public override void RemovePcmData(Time clipBegin, Time clipEnd) { if (clipBegin == null || clipEnd == null) { throw new exception.MethodParameterIsNullException("Clip begin or clip end can not be null"); } //long oneMS = PCMFormat.Data.ConvertTimeToBytes(1); //double timeBlockAlign = PCMFormat.Data.ConvertBytesToTime(PCMFormat.Data.BlockAlign); if ( clipBegin.IsLessThan(Time.Zero) || clipBegin.IsGreaterThan(clipEnd) || clipEnd.IsGreaterThan(AudioDuration)) { throw new exception.MethodParameterIsOutOfBoundsException( String.Format("The given clip times are not valid, must be between 00:00:00.000 and {0} ([{1} --> {2})", AudioDuration, clipBegin, clipEnd)); } Time curBeginTime = Time.Zero; List <WavClip> newClipList = new List <WavClip>(); foreach (WavClip curClip in mWavClips) { Time curEndTime = new Time(curBeginTime.AsTimeSpanTicks + curClip.Duration.AsTimeSpanTicks, true); if ((!curEndTime.IsGreaterThan(clipBegin)) || (!curBeginTime.IsLessThan(clipEnd))) { //The current clip is before or beyond the range to remove - //so the clip is added unaltered to the new list of clips newClipList.Add(curClip); } else if (curBeginTime.IsLessThan(clipBegin) && curEndTime.IsGreaterThan(clipEnd)) { //Some of the current clip is before the range and some is after Time beforePartDur = curBeginTime.GetDifference(clipBegin); Time beyondPartDur = curEndTime.GetDifference(clipEnd); //Time timePointRelativeToClipBeginOfWavClip = new Time( // curClip.Duration.AsTimeSpan - beyondPartDur.AsTimeSpan); //Stream beyondAS = curClip.OpenPcmInputStream(timePointRelativeToClipBeginOfWavClip); //WavClip beyondPartClip; //try //{ // beyondPartClip = new WavClip(CreateDataProviderFromRawPCMStream(beyondAS, null)); //} //finally //{ // beyondAS.Close(); //} WavClip beyondPartClip = curClip.Copy(); Time copyEnd = beyondPartClip.ClipEnd.Copy(); copyEnd.Substract(beyondPartDur); beyondPartClip.ClipBegin = copyEnd; curClip.ClipEnd = new Time(curClip.ClipBegin.AsTimeSpanTicks + beforePartDur.AsTimeSpanTicks, true); newClipList.Add(curClip); newClipList.Add(beyondPartClip); } else if (curBeginTime.IsLessThan(clipBegin) && curEndTime.IsGreaterThan(clipBegin)) { //Some of the current clip is before the range to remove, none is beyond Time beforePartDur = curBeginTime.GetDifference(clipBegin); curClip.ClipEnd = new Time(curClip.ClipBegin.AsTimeSpanTicks + beforePartDur.AsTimeSpanTicks, true); newClipList.Add(curClip); } else if (curBeginTime.IsLessThan(clipEnd) && curEndTime.IsGreaterThan(clipEnd)) { //Some of the current clip is beyond the range to remove, none is before Time beyondPartDur = curEndTime.GetDifference(clipEnd); curClip.ClipBegin = new Time(curClip.ClipEnd.AsTimeSpanTicks - beyondPartDur.AsTimeSpanTicks, true); newClipList.Add(curClip); } curBeginTime = curEndTime; } mWavClips = newClipList; NotifyAudioDataRemoved(this, clipBegin, clipEnd.GetDifference(clipBegin)); }
/// <summary> /// Inserts audio of a given duration from a given source PCM data <see cref="Stream"/> to the wav audio media data /// at a given point /// </summary> /// <param name="pcmData">The source PCM data stream</param> /// <param name="insertPoint">The insert point</param> /// <param name="duration">The duration of the aduio to append</param> public override void InsertPcmData(Stream pcmData, Time insertPoint, Time duration) { WavClip newInsClip = new WavClip(CreateDataProviderFromRawPCMStream(pcmData, duration)); InsertPcmData(newInsClip, insertPoint, duration); }
protected void InsertPcmData(WavClip newInsClip, Time insertPoint, Time duration) { if (insertPoint.IsLessThan(Time.Zero)) { throw new exception.MethodParameterIsOutOfBoundsException( "The given insert point is negative"); } Time endTime = AudioDuration; if (insertPoint.IsGreaterThan(endTime)) { throw new exception.MethodParameterIsOutOfBoundsException( "The given insert point is beyond the end of the WavAudioMediaData"); } checkPcmFormat(newInsClip); if (insertPoint.IsEqualTo(endTime)) { mWavClips.Add(newInsClip); NotifyAudioDataInserted(this, insertPoint, duration); return; } Time elapsedTime = Time.Zero; int clipIndex = 0; while (clipIndex < mWavClips.Count) { WavClip curClip = mWavClips[clipIndex]; if (insertPoint.IsEqualTo(elapsedTime)) { //If the insert point at the beginning of the current clip, insert the new clip and break mWavClips.Insert(clipIndex, newInsClip); break; } if (insertPoint.IsLessThan(new Time(elapsedTime.AsTimeSpanTicks + curClip.Duration.AsTimeSpanTicks, true))) { //If the insert point is between the beginning and end of the current clip, //Replace the current clip with three clips containing //the audio in the current clip before the insert point, //the audio to be inserted and the audio in the current clip after the insert point respectively Time insPtInCurClip = insertPoint.GetDifference(elapsedTime); WavClip curClipBeforeIns = curClip.Copy(); curClipBeforeIns.ClipEnd = curClipBeforeIns.ClipBegin.Copy(); curClipBeforeIns.ClipEnd.Add(insPtInCurClip); //Stream audioDataStream = curClip.OpenPcmInputStream(Time.Zero, insPtInCurClip); //try //{ // curClipBeforeIns = new WavClip(CreateDataProviderFromRawPCMStream(audioDataStream, null)); //} //finally //{ // audioDataStream.Close(); //} WavClip curClipAfterIns = curClip.Copy(); curClipAfterIns.ClipBegin.Add(insPtInCurClip); //audioDataStream = curClip.OpenPcmInputStream(insPtInCurClip); //try //{ // curClipAfterIns = new WavClip(CreateDataProviderFromRawPCMStream(audioDataStream, null)); //} //finally //{ // audioDataStream.Close(); //} mWavClips.RemoveAt(clipIndex); mWavClips.InsertRange(clipIndex, new WavClip[] { curClipBeforeIns, newInsClip, curClipAfterIns }); break; } elapsedTime.Add(curClip.Duration); clipIndex++; } NotifyAudioDataInserted(this, insertPoint, duration); }
/// <summary> /// Gets a <see cref="Stream"/> providing read access to all audio between given clip begin and end <see cref="Time"/>s /// as raw PCM data /// </summary> /// <param name="clipBegin">The given clip begin <see cref="Time"/></param> /// <param name="clipEnd">The given clip end <see cref="Time"/></param> /// <returns>The <see cref="Stream"/></returns> public override Stream OpenPcmInputStream(Time clipBegin, Time clipEnd) { if (clipBegin.IsNegative) { throw new exception.MethodParameterIsOutOfBoundsException( "The clip begin value can not be a negative time"); } if (clipEnd.IsLessThan(clipBegin)) { throw new exception.MethodParameterIsOutOfBoundsException( "The clip end can not be before clip begin"); } if (clipEnd.IsGreaterThan(AudioDuration)) { throw new exception.MethodParameterIsOutOfBoundsException( "The clip end can not beyond the end of the audio content"); } if (mWavClips.Count == 0) { Debug.Fail("That's probably going to create problems ?"); return(new MemoryStream(0)); } if (mWavClips.Count == 1) { return(mWavClips[0].OpenPcmInputStream( clipBegin, clipEnd)); } Time elapsedTime = new Time(); int i = 0; #if USE_NORMAL_LIST List #else LightLinkedList #endif //USE_NORMAL_LIST <Stream> resStreams = new #if USE_NORMAL_LIST List #else LightLinkedList #endif //USE_NORMAL_LIST <Stream>(); while (i < mWavClips.Count) { WavClip curClip = mWavClips[i]; Time currentClipDuration = curClip.Duration; Time newElapsedTime = new Time(elapsedTime.AsTimeSpanTicks + currentClipDuration.AsTimeSpanTicks, true); if (newElapsedTime.IsLessThan(clipBegin)) { //Do nothing - the current clip and the [clipBegin;clipEnd] are disjunkt } else if (elapsedTime.IsLessThan(clipBegin)) { if (newElapsedTime.IsLessThan(clipEnd)) { //Add part of current clip between clipBegin and newElapsedTime //(ie. after clipBegin, since newElapsedTime is at the end of the clip) resStreams.Add(curClip.OpenPcmInputStream( clipBegin.GetDifference(elapsedTime))); } else { //Add part of current clip between clipBegin and clipEnd resStreams.Add(curClip.OpenPcmInputStream( clipBegin.GetDifference(elapsedTime), clipEnd.GetDifference(elapsedTime))); } } else if (elapsedTime.IsLessThan(clipEnd)) { if (newElapsedTime.IsLessThan(clipEnd)) { //Add part of current clip between elapsedTime and newElapsedTime //(ie. entire clip since elapsedTime and newElapsedTime is at //the beginning and end of the clip respectively) resStreams.Add(curClip.OpenPcmInputStream()); } else { //Add part of current clip between elapsedTime and clipEnd //(ie. before clipEnd since elapsedTime is at the beginning of the clip) resStreams.Add(curClip.OpenPcmInputStream( Time.Zero, clipEnd.GetDifference(elapsedTime))); } } else { //The current clip and all remaining clips are beyond clipEnd break; } elapsedTime = newElapsedTime; i++; } if (resStreams.IsEmpty) { Debug.Fail("That's probably going to create problems ?"); return(new MemoryStream(0)); } return(new SequenceStream(resStreams)); }
/// <summary> /// Splits the audio media data at a given split point in time, /// <c>this</c> retaining the audio before the split point, /// creating a new <see cref="WavAudioMediaData"/> containing the audio after the split point /// </summary> /// <param name="splitPoint">The given split point</param> /// <returns>A audio media data containing the audio after the split point</returns> /// <exception cref="exception.MethodParameterIsNullException"> /// Thrown when the given split point is <c>null</c> /// </exception> /// <exception cref="exception.MethodParameterIsOutOfBoundsException"> /// Thrown when the given split point is negative or is beyond the duration of <c>this</c> /// </exception> public override AudioMediaData Split(Time splitPoint) { if (splitPoint == null) { throw new exception.MethodParameterIsNullException( "The split point can not be null"); } if (splitPoint.IsNegative) { throw new exception.MethodParameterIsOutOfBoundsException( "The split point can not be negative"); } if (splitPoint.IsGreaterThan(AudioDuration)) { throw new exception.MethodParameterIsOutOfBoundsException( String.Format( "Split point {0} is beyond the WavAudioMediaData end - audio length is {1}", splitPoint, AudioDuration)); } WavAudioMediaData oWAMD = Presentation.MediaDataFactory.Create <WavAudioMediaData>(); if (oWAMD == null) { throw new exception.FactoryCannotCreateTypeException(String.Format( "Thrown if the MediaDataFactory can not create a WacAudioMediaData matching Xuk QName {1}:{0}", GetXukName(), GetXukNamespace())); } oWAMD.PCMFormat = PCMFormat.Copy(); Time originalDuration = AudioDuration; Time newClipDuration = AudioDuration.GetDifference(splitPoint); Time curClip_Begin = Time.Zero; List <WavClip> clips = new List <WavClip>(mWavClips); mWavClips.Clear(); oWAMD.mWavClips.Clear(); for (int i = 0; i < clips.Count; i++) { WavClip curClip = clips[i]; Time savedCurClipDuration = curClip.Duration; Time curClip_End = new Time(curClip_Begin.AsTimeSpanTicks + curClip.Duration.AsTimeSpanTicks, true); if (splitPoint.IsLessThanOrEqualTo(curClip_Begin)) { oWAMD.mWavClips.Add(curClip); } else if (splitPoint.IsLessThan(curClip_End)) { WavClip secondPartClip = new WavClip( curClip.DataProvider, curClip.ClipBegin, curClip.IsClipEndTiedToEOM ? null : curClip.ClipEnd); curClip.ClipEnd = new Time(curClip.ClipBegin.AsTimeSpanTicks + (splitPoint.AsTimeSpanTicks - curClip_Begin.AsTimeSpanTicks), true); secondPartClip.ClipBegin = curClip.ClipEnd.Copy(); mWavClips.Add(curClip); oWAMD.mWavClips.Add(secondPartClip); } else { mWavClips.Add(curClip); } curClip_Begin.Add(savedCurClipDuration); } NotifyAudioDataRemoved(this, splitPoint, newClipDuration); oWAMD.NotifyAudioDataInserted(oWAMD, Time.Zero, newClipDuration); #if DEBUG DebugFix.Assert(AudioLibPCMFormat.TimesAreEqualWithMillisecondsTolerance( newClipDuration.AsLocalUnits, oWAMD.AudioDuration.AsLocalUnits)); DebugFix.Assert(newClipDuration.IsEqualTo(oWAMD.AudioDuration)); DebugFix.Assert(AudioLibPCMFormat.TimesAreEqualWithMillisecondsTolerance( this.AudioDuration.AsLocalUnits + oWAMD.AudioDuration.AsLocalUnits, originalDuration.AsLocalUnits)); Time copy = this.AudioDuration.Copy(); copy.Add(oWAMD.AudioDuration); DebugFix.Assert(originalDuration.IsEqualTo(copy)); #endif //DEBUG return(oWAMD); }