diff --git a/Vocaluxe.sln.DotSettings b/Vocaluxe.sln.DotSettings index d5a12790..62cdef16 100644 --- a/Vocaluxe.sln.DotSettings +++ b/Vocaluxe.sln.DotSettings @@ -10,7 +10,7 @@ DO_NOT_SHOW DO_NOT_SHOW <?xml version="1.0" encoding="utf-16"?><Profile name="Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_BOTH</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSShortenReferences>True</CSShortenReferences><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSUpdateFileHeader>True</CSUpdateFileHeader><CSUseAutoProperty>True</CSUseAutoProperty></Profile> - <?xml version="1.0" encoding="utf-16"?><Profile name="Simple Reformat"><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSShortenReferences>True</CSShortenReferences><CSUseVar><BehavourStyle>CAN_CHANGE_BOTH</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>IMPLICIT_EXCEPT_PRIMITIVE_TYPES</ForeachVariableStyle></CSUseVar></Profile> + <?xml version="1.0" encoding="utf-16"?><Profile name="Simple Reformat"><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectives>Ignore</ExpandUsingDirectives><SA1212PropertyAccessorsMustFollowOrder>True</SA1212PropertyAccessorsMustFollowOrder><SA1213EventAccessorsMustFollowOrder>True</SA1213EventAccessorsMustFollowOrder></StyleCop.Ordering><CSShortenReferences>True</CSShortenReferences><CSUseVar><BehavourStyle>CAN_CHANGE_BOTH</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar></Profile> Cleanup Simple Reformat 0 diff --git a/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs b/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs index 22787416..15e06b56 100644 --- a/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs +++ b/Vocaluxe/Lib/Sound/Decoder/CAudioDecoderFFmpeg.cs @@ -57,7 +57,7 @@ namespace Vocaluxe.Lib.Sound.Decoder if (!_Instance.Opened) { - //Free(); + Close(); return; } @@ -72,12 +72,13 @@ namespace Vocaluxe.Lib.Sound.Decoder catch (Exception) { CLog.LogError("Error opening audio file (can't find decoder): " + _FileName); + Close(); return; } if (audioStreamIndex < 0) { - //Free(); + Close(); return; } @@ -93,6 +94,7 @@ namespace Vocaluxe.Lib.Sound.Decoder if (_FormatInfo.BitDepth != 16) { CLog.LogError("Unsupported BitDepth in file " + fileName); + Close(); return; } _FileOpened = true; @@ -100,35 +102,29 @@ namespace Vocaluxe.Lib.Sound.Decoder public void Close() { - if (!_FileOpened) - return; - if (_Audiodecoder != IntPtr.Zero) + { CAcinerella.AcFreeDecoder(_Audiodecoder); - + _Audiodecoder = IntPtr.Zero; + } if (_InstancePtr != IntPtr.Zero) + { CAcinerella.AcClose(_InstancePtr); - - if (_InstancePtr != IntPtr.Zero) CAcinerella.AcFree(_InstancePtr); + _InstancePtr = IntPtr.Zero; + } _FileOpened = false; } public SFormatInfo GetFormatInfo() { - if (!_FileOpened) - return new SFormatInfo(); - - return _FormatInfo; + return _FileOpened ? _FormatInfo : new SFormatInfo(); } public float GetLength() { - if (!_FileOpened) - return 0f; - - return _Instance.Info.Duration / 1000f; + return _FileOpened ? _Instance.Info.Duration / 1000f:0; } public void SetPosition(float time) @@ -138,7 +134,7 @@ namespace Vocaluxe.Lib.Sound.Decoder try { - CAcinerella.AcSeek(_Audiodecoder, 0, (Int64)(time * 1000f)); + CAcinerella.AcSeek(_Audiodecoder, (time>_CurrentTime)?0:-1, (Int64)(time * 1000f)); } catch (Exception) { @@ -149,7 +145,7 @@ namespace Vocaluxe.Lib.Sound.Decoder public float GetPosition() { - return !_FileOpened ? 0f : _CurrentTime; + return _FileOpened ? _CurrentTime : 0f; } public void Decode(out byte[] buffer, out float timeStamp) @@ -161,17 +157,9 @@ namespace Vocaluxe.Lib.Sound.Decoder return; } - int frameFinished; - try - { - frameFinished = CAcinerella.AcGetAudioFrame(_InstancePtr, _Audiodecoder); - } - catch (Exception) - { - frameFinished = 0; - } + bool frameFinished = CAcinerella.AcGetAudioFrame(_InstancePtr, _Audiodecoder); - if (frameFinished == 1) + if (frameFinished) { SACDecoder decoder = (SACDecoder)Marshal.PtrToStructure(_Audiodecoder, typeof(SACDecoder)); diff --git a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs index 3851b485..bfc814c9 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs @@ -156,11 +156,7 @@ namespace Vocaluxe.Lib.Video.Acinerella // the number of bytes read or an value smaller than zero if an error occured. //TAc_read_callback = function(sender: Pointer; byte[] buf, int size): integer; cdecl; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate Int32 ACReadCallback( - IntPtr sender, - IntPtr buf, - Int32 size - ); + public delegate Int32 ACReadCallback(IntPtr sender, IntPtr buf, Int32 size); // Callback function used to ask the application to seek. return 0 if succeed , -1 on failure. //TAc_seek_callback = function(sender: Pointer; pos: int64; whence: integer): int64; cdecl; @@ -274,17 +270,11 @@ namespace Vocaluxe.Lib.Video.Acinerella }*/ [DllImport(_AcDll, EntryPoint = "ac_open", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - private static extern Int32 _ac_open2( - IntPtr pAcInstance, - string filename - ); + private static extern Int32 _ac_open2(IntPtr pAcInstance, string filename); // ReSharper disable UnusedMethodReturnValue.Global - public static Int32 AcOpen2( + public static Int32 AcOpen2(IntPtr pAcInstance, string filename) // ReSharper restore UnusedMethodReturnValue.Global - IntPtr pAcInstance, - string filename - ) { lock (_Lock) { @@ -306,28 +296,15 @@ namespace Vocaluxe.Lib.Video.Acinerella } // Stores information in "pInfo" about stream number "nb". - //procedure ac_get_stream_info( - //inst: PAc_instance; nb: integer; pinfo: PAc_stream_info); cdecl; external ac_dll; + //procedure ac_get_stream_info(inst: PAc_instance; nb: integer; pinfo: PAc_stream_info); cdecl; external ac_dll; [DllImport(_AcDll, EntryPoint = "ac_get_stream_info", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] - private static extern void _ac_get_stream_info( - IntPtr pAcInstance, - Int32 nb, - out SACStreamInfo info - ); + private static extern void _ac_get_stream_info(IntPtr pAcInstance, Int32 nb, out SACStreamInfo info); - public static void AcGetStreamInfo( - IntPtr pAcInstance, - Int32 nb, - out SACStreamInfo info - ) + public static void AcGetStreamInfo(IntPtr pAcInstance, Int32 nb, out SACStreamInfo info) { lock (_Lock) { - _ac_get_stream_info( - pAcInstance, - nb, - out info - ); + _ac_get_stream_info(pAcInstance, nb, out info); } } @@ -382,44 +359,44 @@ namespace Vocaluxe.Lib.Video.Acinerella [DllImport(_AcDll, EntryPoint = "ac_decode_package", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_decode_package(IntPtr pAcPackage, IntPtr pAcDecoder); - public static Int32 AcDecodePackage(IntPtr pAcPackage, IntPtr pAcDecoder) + public static bool AcDecodePackage(IntPtr pAcPackage, IntPtr pAcDecoder) { lock (_Lock) { - return _ac_decode_package(pAcPackage, pAcDecoder); + return _ac_decode_package(pAcPackage, pAcDecoder)!=0; } } [DllImport(_AcDll, EntryPoint = "ac_get_audio_frame", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_get_audio_frame(IntPtr pAcInstance, IntPtr pAcDecoder); - public static Int32 AcGetAudioFrame(IntPtr pAcInstance, IntPtr pAcDecoder) + public static bool AcGetAudioFrame(IntPtr pAcInstance, IntPtr pAcDecoder) { lock (_Lock) { - return _ac_get_audio_frame(pAcInstance, pAcDecoder); + return _ac_get_audio_frame(pAcInstance, pAcDecoder)!=0; } } [DllImport(_AcDll, EntryPoint = "ac_get_frame", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_get_frame(IntPtr pAcInstance, IntPtr pAcDecoder); - public static Int32 AcGetFrame(IntPtr pAcInstance, IntPtr pAcDecoder) + public static bool AcGetFrame(IntPtr pAcInstance, IntPtr pAcDecoder) { lock (_Lock) { - return _ac_get_frame(pAcInstance, pAcDecoder); + return _ac_get_frame(pAcInstance, pAcDecoder)!=0; } } [DllImport(_AcDll, EntryPoint = "ac_skip_frames", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_skip_frames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num); - public static Int32 AcSkipFrames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num) + public static bool AcSkipFrames(IntPtr pAcInstance, IntPtr pAcDecoder, Int32 num) { lock (_Lock) { - return _ac_skip_frames(pAcInstance, pAcDecoder, num); + return _ac_skip_frames(pAcInstance, pAcDecoder, num)!=0; } } @@ -431,25 +408,18 @@ namespace Vocaluxe.Lib.Video.Acinerella [DllImport(_AcDll, EntryPoint = "ac_seek", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] private static extern Int32 _ac_seek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos); - // ReSharper disable UnusedMethodReturnValue.Global - public static Int32 AcSeek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos) - // ReSharper restore UnusedMethodReturnValue.Global + public static bool AcSeek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos) { lock (_Lock) { - return _ac_seek(pAcDecoder, dir, targetPos); + return _ac_seek(pAcDecoder, dir, targetPos)!=0; } } //function ac_probe_input_buffer(buf: PChar; bufsize: Integer; filename: PChar; //var score_max: Integer): PAc_proberesult; cdecl; external ac_dll; [DllImport(_AcDll, EntryPoint = "ac_probe_input_buffer", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] - public static extern IntPtr ac_probe_input_buffer( - IntPtr buf, - Int32 bufsize, - IntPtr filename, - out Int32 scoreMax - ); + public static extern IntPtr ac_probe_input_buffer(IntPtr buf, Int32 bufsize, IntPtr filename, out Int32 scoreMax); } // ReSharper restore UnusedMember.Global diff --git a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs index e5041906..dd009248 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs @@ -14,51 +14,46 @@ namespace Vocaluxe.Lib.Video.Acinerella private IntPtr _Videodecoder = IntPtr.Zero; // acinerella video decoder instance private readonly Stopwatch _LoopTimer = new Stopwatch(); - private string _FileName; // current video file name + private readonly Thread _Thread; + //AutoResetEvent EventDecode = new AutoResetEvent(false); + private readonly Object _MutexFramebuffer = new Object(); + private readonly SFrameBuffer[] _FrameBuffer = new SFrameBuffer[5]; + private readonly Object _MutexSyncSignals = new Object(); private bool _FileOpened; - private float _VideoTimeBase; // frame time - private float _VideoDecoderTime; // time of last decoded frame - private float _CurrentVideoTime; // current video position + private float _FrameDuration; // frame time in s + private float _LastDecodedTime; // time of last decoded frame + private float _LastShownTime; // current video position private bool _BufferFull; // buffer is full, waiting for free frame slot private float _Time; private float _Gap; private float _Start; private bool _Loop; - private float _Duration; - private float _VideoSkipTime; // = VideoGap - private float _SkipTime; // = Start + VideoGap - private bool _Paused; - private bool _NoMoreFrames; - private bool _BeforeLoop; - - private int _Width; - private int _Height; private float _SetTime; private float _SetGap; private float _SetStart; private bool _SetSkip; - private bool _Terminated; - private readonly Thread _Thread; - //AutoResetEvent EventDecode = new AutoResetEvent(false); - private readonly SFrameBuffer[] _FrameBuffer = new SFrameBuffer[5]; - private bool _NewFrame; - private readonly Object _MutexFramebuffer = new Object(); - private readonly Object _MutexSyncSignals = new Object(); + private bool _Terminated; + private bool _FrameAvailable; + private bool _NoMoreFrames; + + private float _SkipTime; // = Start + VideoGap + + private string _FileName; // current video file name + private int _Width; + private int _Height; + private bool _Paused; public CDecoder() { _Thread = new Thread(_Execute); } - public float Length - { - get { return _FileOpened ? _Duration : 0f; } - } + public float Length { get; private set; } public bool Paused { @@ -104,43 +99,40 @@ namespace Vocaluxe.Lib.Video.Acinerella public void Close() { _Terminated = true; + Length = 0; } public bool GetFrame(ref CTexture frame, float time, out float videoTime) { - videoTime = 0; - if (_Paused) + { + videoTime = 0; return false; + } if (Loop) { lock (_MutexSyncSignals) { _SetTime += _LoopTimer.ElapsedMilliseconds / 1000f; - videoTime = _SetTime; - _LoopTimer.Restart(); } - - - _UploadNewFrame(ref frame); - //EventDecode.Set(); - return frame != null; } - - if (Math.Abs(_SetTime - time) > float.Epsilon) + else if (Math.Abs(_SetTime - time) > float.Epsilon) { lock (_MutexSyncSignals) { _SetTime = time; } - _UploadNewFrame(ref frame); - videoTime = _CurrentVideoTime; - //EventDecode.Set(); - return frame != null; } - return false; + else + { + videoTime = 0; + return false; + } + _UploadNewFrame(ref frame); + videoTime = _LastShownTime; + return frame != null; } public bool Skip(float start, float gap) @@ -153,74 +145,51 @@ namespace Vocaluxe.Lib.Video.Acinerella _NoMoreFrames = false; Finished = false; } - //EventDecode.Set(); return true; } #region Threading private void _Skip() { - _VideoSkipTime = _Gap; _SkipTime = _Start + _Gap; - _BeforeLoop = false; - if (_SkipTime > 0) + if (_SkipTime < 0) + _SkipTime = 0; + + try { - _VideoDecoderTime = _SkipTime; - try - { - CAcinerella.AcSeek(_Videodecoder, -1, (Int64)(_SkipTime * 1000f)); - } - catch (Exception e) - { - CLog.LogError("Error seeking video file \"" + _FileName + "\": " + e.Message); - } + CAcinerella.AcSeek(_Videodecoder, (_LastDecodedTime > _SkipTime) ? -1 : 0, (Int64)(_SkipTime * 1000f)); } - else + catch (Exception e) { - _VideoDecoderTime = 0f; - try - { - CAcinerella.AcSeek(_Videodecoder, -1, 0); - } - catch (Exception e) - { - CLog.LogError("Error seeking video file \"" + _FileName + "\": " + e.Message); - } + CLog.LogError("Error seeking video file \"" + _FileName + "\": " + e.Message); } + _LastDecodedTime = _SkipTime; lock (_MutexSyncSignals) { - _CurrentVideoTime = _VideoDecoderTime; + _LastShownTime = _LastDecodedTime; } lock (_MutexFramebuffer) { for (int i = 0; i < _FrameBuffer.Length; i++) - { _FrameBuffer[i].Displayed = true; - _FrameBuffer[i].Time = -1f; - } } _BufferFull = false; - _NewFrame = false; - //EventDecode.Set(); + _FrameAvailable = false; } private void _Execute() { - //EventDecode.Set(); while (!_Terminated) { - //if (EventDecode.WaitOne(10)) - bool skip = false; + bool skip; lock (_MutexSyncSignals) { _Time = _SetTime; - if (_SetSkip) - skip = true; - + skip = _SetSkip; _SetSkip = false; _Gap = _SetGap; _Start = _SetStart; @@ -230,10 +199,10 @@ namespace Vocaluxe.Lib.Video.Acinerella if (skip) _Skip(); - if (!_NewFrame) + if (!_FrameAvailable) _Decode(); - if (_NewFrame) + if (_FrameAvailable && !_BufferFull) _Copy(); Thread.Sleep(1); } @@ -249,8 +218,8 @@ namespace Vocaluxe.Lib.Video.Acinerella _Instance = CAcinerella.AcInit(); CAcinerella.AcOpen2(_Instance, _FileName); - SACInstance instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance)); - _Duration = instance.Info.Duration / 1000f; + var instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance)); + Length = instance.Info.Duration / 1000f; ok = instance.Opened; } catch (Exception) @@ -279,7 +248,6 @@ namespace Vocaluxe.Lib.Video.Acinerella return false; } - if (videoStreamIndex < 0) { _Free(); @@ -290,18 +258,18 @@ namespace Vocaluxe.Lib.Video.Acinerella _Height = videodecoder.StreamInfo.VideoInfo.FrameHeight; if (videodecoder.StreamInfo.VideoInfo.FramesPerSecond > 0) - _VideoTimeBase = 1f / (float)videodecoder.StreamInfo.VideoInfo.FramesPerSecond; + _FrameDuration = 1f / (float)videodecoder.StreamInfo.VideoInfo.FramesPerSecond; - _VideoDecoderTime = 0f; + _LastDecodedTime = 0f; _Time = 0f; for (int i = 0; i < _FrameBuffer.Length; i++) { - _FrameBuffer[i].Time = -1f; _FrameBuffer[i].Displayed = true; _FrameBuffer[i].Data = new byte[_Width * _Height * 4]; } - + _BufferFull = false; + _FrameAvailable = false; return true; } @@ -309,25 +277,19 @@ namespace Vocaluxe.Lib.Video.Acinerella { const int framedropcount = 4; - if (_NewFrame) - return; - if (_Paused || _NoMoreFrames || _BufferFull) return; - if ((_SkipTime < 0f) && (_Time + _SkipTime >= 0f)) - _SkipTime = 0f; + float myTime = _Time + _Gap; + float timeDifference = myTime - _LastDecodedTime; - float myTime = _Time + _VideoSkipTime; - float timeDifference = myTime - _VideoDecoderTime; - - bool dropFrame = timeDifference >= (framedropcount - 1) * _VideoTimeBase; + bool dropFrame = timeDifference >= (framedropcount - 1) * _FrameDuration; if (_Terminated) return; - int frameFinished = 0; - if (dropFrame && !_BeforeLoop) + bool frameFinished = false; + if (dropFrame) { try { @@ -339,7 +301,7 @@ namespace Vocaluxe.Lib.Video.Acinerella } } - if (!_BeforeLoop && (!dropFrame || frameFinished != 0)) + if (!frameFinished) { try { @@ -350,61 +312,30 @@ namespace Vocaluxe.Lib.Video.Acinerella CLog.LogError("Error AcGetFrame " + _FileName); } } - - if (frameFinished == 0) + if (frameFinished) + _FrameAvailable = true; + else { if (_Loop) { - _BeforeLoop = true; - bool doskip = true; - float tm = 0f; - int num = -1; - lock (_MutexFramebuffer) - { - for (int i = 0; i < _FrameBuffer.Length; i++) - { - if (_FrameBuffer[i].Time > tm && !_FrameBuffer[i].Displayed) - { - tm = _FrameBuffer[i].Time; - num = i; - } - } - - if (num >= 0) - doskip = _FrameBuffer[num].Displayed; - } - - if (!doskip) - return; - lock (_MutexSyncSignals) { _Start = 0f; _Gap = 0f; _SetTime = 0f; } - _Skip(); } else _NoMoreFrames = true; } - else - { - _NewFrame = true; - _Copy(); - } } private void _Copy() { - if (!_NewFrame) - return; - - int num = -1; - lock (_MutexFramebuffer) { + int num = -1; for (int i = 0; i < _FrameBuffer.Length; i++) { if (_FrameBuffer[i].Displayed) @@ -415,32 +346,31 @@ namespace Vocaluxe.Lib.Video.Acinerella } if (num == -1) - _BufferFull = true; + _BufferFull = true; //Should not happen else { - SACDecoder videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); + var videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); - _VideoDecoderTime = (float)videodecoder.Timecode; - _FrameBuffer[num].Time = _VideoDecoderTime; + _LastDecodedTime = (float)videodecoder.Timecode; + _FrameBuffer[num].Time = _LastDecodedTime; if (videodecoder.Buffer != IntPtr.Zero) { Marshal.Copy(videodecoder.Buffer, _FrameBuffer[num].Data, 0, _Width * _Height * 4); - _FrameBuffer[num].Displayed = false; } - int numfull = 0; - for (int i = 0; i < _FrameBuffer.Length; i++) + _BufferFull = true; + for (int i = num + 1; i < _FrameBuffer.Length; i++) { - if (!_FrameBuffer[i].Displayed) - numfull++; + if (_FrameBuffer[i].Displayed) + { + _BufferFull = false; + break; + } } - if (numfull < _FrameBuffer.Length) - _BufferFull = false; - - _NewFrame = false; + _FrameAvailable = false; } } } @@ -457,7 +387,7 @@ namespace Vocaluxe.Lib.Video.Acinerella lock (_MutexSyncSignals) { - _CurrentVideoTime = _FrameBuffer[num].Time; + _LastShownTime = _FrameBuffer[num].Time; } Finished = false; } @@ -476,14 +406,20 @@ namespace Vocaluxe.Lib.Video.Acinerella for (int i = 0; i < _FrameBuffer.Length; i++) { - float td = _SetTime + _VideoSkipTime - _FrameBuffer[i].Time; + if (_FrameBuffer[i].Displayed) + continue; - if (td > _VideoTimeBase * 2f) - _FrameBuffer[i].Displayed = true; + // Time from frame till now (<0 --> Frame is not yet to be shown) + float td = _SetTime + _Gap - _FrameBuffer[i].Time; - if (!_FrameBuffer[i].Displayed && (td < diff) && (td > _VideoTimeBase)) + if (td > _FrameDuration * 2f) { - diff = Math.Abs(_FrameBuffer[i].Time - _SetTime - _VideoSkipTime); + _FrameBuffer[i].Displayed = true; + _BufferFull = false; + } + else if (td < diff && td > _FrameDuration) + { + diff = Math.Abs(td); result = i; } }