diff --git a/Vocaluxe.sln.DotSettings b/Vocaluxe.sln.DotSettings
index 473f1044..33cad2d0 100644
--- a/Vocaluxe.sln.DotSettings
+++ b/Vocaluxe.sln.DotSettings
@@ -9,8 +9,8 @@
DO_NOT_SHOW
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_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_EXPLICIT</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></Profile>
+ <?xml version="1.0" encoding="utf-16"?><Profile name="Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</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_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar></Profile>
Cleanup
Simple Reformat
0
diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs
index 26377f1d..a47de520 100644
--- a/Vocaluxe/Base/CBackgroundMusic.cs
+++ b/Vocaluxe/Base/CBackgroundMusic.cs
@@ -55,14 +55,9 @@ namespace Vocaluxe.Base
get { return _VideoEnabled; }
set
{
- if (_VideoEnabled && value)
+ if (_VideoEnabled == value)
return;
- if (!_VideoEnabled && !value)
- return;
- if (_VideoEnabled && !value)
- ToggleVideo();
- if (!_VideoEnabled && value)
- ToggleVideo();
+ ToggleVideo();
_VideoEnabled = value;
}
}
@@ -126,7 +121,7 @@ namespace Vocaluxe.Base
public static void Init()
{
- List templist = new List();
+ var templist = new List();
foreach (string ending in CSettings.MusicFileTypes)
templist.AddRange(CHelper.ListFiles(CSettings.FolderBackgroundMusic, ending, true, true));
@@ -136,8 +131,8 @@ namespace Vocaluxe.Base
if (CConfig.BackgroundMusicSource != EBackgroundMusicSource.TR_CONFIG_ONLY_OWN_MUSIC)
AddBackgroundMusic();
- if (CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON)
- _VideoEnabled = true;
+
+ _VideoEnabled = (CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON);
IsPlaying = false;
}
@@ -439,20 +434,9 @@ namespace Vocaluxe.Base
{
if (_Video != -1)
{
- if (_VideoEnabled)
- {
- _VideoEnabled = false;
- CVideo.Close(_Video);
- _Video = -1;
- CDraw.RemoveTexture(ref _CurrentVideoTexture);
- return;
- }
- if (CVideo.Finished(_Video))
- {
- CVideo.Close(_Video);
- CDraw.RemoveTexture(ref _CurrentVideoTexture);
- _Video = -1;
- }
+ CVideo.Close(_Video);
+ CDraw.RemoveTexture(ref _CurrentVideoTexture);
+ _Video = -1;
}
else
_LoadVideo();
@@ -485,17 +469,15 @@ namespace Vocaluxe.Base
private static void _LoadVideo()
{
- if (_Video == -1)
- {
- _Video = CVideo.Load(_CurrentPlaylistElement.VideoFilePath);
- if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON)
- CVideo.Skip(_Video, _CurrentPlaylistElement.Start, _CurrentPlaylistElement.VideoGap);
- else
- CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap);
- _VideoEnabled = true;
- _FadeTimer.Reset();
- _FadeTimer.Start();
- }
+ if (_Video != -1 || String.IsNullOrEmpty(_CurrentPlaylistElement.VideoFilePath))
+ return;
+ _Video = CVideo.Load(_CurrentPlaylistElement.VideoFilePath);
+ if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON)
+ CVideo.Skip(_Video, _CurrentPlaylistElement.Start, _CurrentPlaylistElement.VideoGap);
+ else
+ CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap);
+ _FadeTimer.Reset();
+ _FadeTimer.Start();
}
}
diff --git a/Vocaluxe/Base/CParty.cs b/Vocaluxe/Base/CParty.cs
index 461f2269..32b283c8 100644
--- a/Vocaluxe/Base/CParty.cs
+++ b/Vocaluxe/Base/CParty.cs
@@ -68,7 +68,7 @@ namespace Vocaluxe.Base
_IDs.Enqueue(i);
//add dummy normal game mode and set it as default
- SPartyMode pm = new SPartyMode {PartyMode = new CPartyModeNone(), ScreenFiles = new List()};
+ var pm = new SPartyMode {PartyMode = new CPartyModeNone(), ScreenFiles = new List()};
pm.PartyMode.Initialize();
pm.PartyModeID = _IDs.Dequeue();
_NormalGameModeID = pm.PartyModeID;
@@ -97,9 +97,9 @@ namespace Vocaluxe.Base
public static List GetPartyModeInfos()
{
- List infos = new List();
+ var infos = new List();
- int[] pmIDs = new int[_PartyModes.Count];
+ var pmIDs = new int[_PartyModes.Count];
_PartyModes.Keys.CopyTo(pmIDs, 0);
foreach (int pmID in pmIDs)
@@ -111,7 +111,7 @@ namespace Vocaluxe.Base
if (mode.PartyMode != null)
{
- SPartyModeInfos info = new SPartyModeInfos
+ var info = new SPartyModeInfos
{
Author = mode.Author,
Description = mode.Description,
@@ -219,7 +219,7 @@ namespace Vocaluxe.Base
#region private stuff
private static void _LoadPartyModes()
{
- List files = new List();
+ var files = new List();
files.AddRange(CHelper.ListFiles(CSettings.FolderPartyModes, "*.xml", false, true));
foreach (string file in files)
@@ -231,7 +231,7 @@ namespace Vocaluxe.Base
private static SPartyMode _LoadPartyMode(string file)
{
- SPartyMode pm = new SPartyMode {PartyModeID = _IDs.Dequeue(), ScreenFiles = new List(), NoErrors = false};
+ var pm = new SPartyMode {PartyModeID = _IDs.Dequeue(), ScreenFiles = new List(), NoErrors = false};
CXMLReader xmlReader = CXMLReader.OpenFile(file);
@@ -272,7 +272,7 @@ namespace Vocaluxe.Base
string pathToCode = Path.Combine(Path.Combine(CSettings.FolderPartyModes, pm.Folder), CSettings.FolderPartyModeCode);
- List filesToCompile = new List();
+ var filesToCompile = new List();
filesToCompile.AddRange(CHelper.ListFiles(pathToCode, "*.cs", false, true));
Assembly output = _CompileFiles(filesToCompile.ToArray());
@@ -304,7 +304,7 @@ namespace Vocaluxe.Base
pm.PartyMode.Initialize();
pm.PartyMode.SetFolder(Path.Combine(Directory.GetCurrentDirectory(), Path.Combine(CSettings.FolderPartyModes, pm.Folder)));
- if (!CTheme.AddTheme(Path.Combine(Directory.GetCurrentDirectory(), Path.Combine(Path.Combine(CSettings.FolderPartyModes, pm.Folder), "Theme.xml")), pm.PartyModeID))
+ if (!CTheme.AddTheme(Path.Combine(pm.PartyMode.GetFolder(), "Theme.xml"),pm.PartyModeID))
return pm;
int themeIndex = CTheme.GetThemeIndex(pm.PartyModeID);
@@ -325,7 +325,7 @@ namespace Vocaluxe.Base
if (screen != null)
{
screen.Init();
- screen.AssingPartyMode(pm.PartyMode);
+ screen.AssignPartyMode(pm.PartyMode);
screen.SetPartyModeID(pm.PartyModeID);
screen.LoadTheme(xmlPath);
pm.PartyMode.AddScreen(screen, screenfile);
@@ -343,7 +343,7 @@ namespace Vocaluxe.Base
if (files == null || files.Length == 0)
return null;
- CompilerParameters compilerParams = new CompilerParameters();
+ var compilerParams = new CompilerParameters();
compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
compilerParams.ReferencedAssemblies.Add("System.Core.dll");
compilerParams.ReferencedAssemblies.Add("VocaluxeLib.dll");
diff --git a/Vocaluxe/Base/CTheme.cs b/Vocaluxe/Base/CTheme.cs
index 9461dbda..7f08c8e9 100644
--- a/Vocaluxe/Base/CTheme.cs
+++ b/Vocaluxe/Base/CTheme.cs
@@ -44,13 +44,15 @@ namespace Vocaluxe.Base
public int PartyModeID;
}
- struct SSkinElement
+ class CSkinElement
{
- public string Name;
public string Value;
-
public CTexture Texture;
- public int VideoIndex;
+ }
+
+ class CVideoSkinElement : CSkinElement
+ {
+ public int VideoIndex = -1;
}
struct SSkin
@@ -64,8 +66,8 @@ namespace Vocaluxe.Base
public string FileName;
public int PartyModeID;
- public Dictionary SkinList;
- public List VideoList;
+ public Dictionary SkinList;
+ public Dictionary VideoList;
public SColors ThemeColors;
}
@@ -111,9 +113,9 @@ namespace Vocaluxe.Base
{
get
{
- List names = new List();
+ var names = new List();
// ReSharper disable LoopCanBeConvertedToQuery
- foreach (STheme th in _Themes)
+ foreach (var th in _Themes)
// ReSharper restore LoopCanBeConvertedToQuery
{
if (th.PartyModeID == -1)
@@ -128,9 +130,9 @@ namespace Vocaluxe.Base
{
get
{
- List names = new List();
+ var names = new List();
// ReSharper disable LoopCanBeConvertedToQuery
- foreach (SSkin sk in _Skins)
+ foreach (var sk in _Skins)
// ReSharper restore LoopCanBeConvertedToQuery
{
if (sk.PartyModeID == -1)
@@ -172,48 +174,34 @@ namespace Vocaluxe.Base
if (xmlReader == null)
return false;
- string value;
-
-
// load skins/textures
- List keys = new List(_Skins[skinIndex].SkinList.Keys);
-
- foreach (string name in keys)
+ foreach (var valuePair in _Skins[skinIndex].SkinList)
{
+ CSkinElement sk = valuePair.Value;
try
{
- xmlReader.GetValue("//root/Skins/" + name, out value, String.Empty);
- SSkinElement sk = _Skins[skinIndex].SkinList[name];
- sk.Value = value;
- sk.VideoIndex = -1;
+ xmlReader.GetValue("//root/Skins/" + valuePair.Key, out sk.Value, String.Empty);
sk.Texture = CDraw.AddTexture(Path.Combine(_Skins[skinIndex].Path, sk.Value));
- _Skins[skinIndex].SkinList[name] = sk;
}
catch (Exception e)
{
- MessageBox.Show("Error on loading texture \"" + name + "\": " + e.Message + e.StackTrace);
- CLog.LogError("Error on loading texture \"" + name + "\": " + e.Message + e.StackTrace);
+ MessageBox.Show("Error on loading texture \"" + valuePair.Key + "\": " + e.Message + e.StackTrace);
+ CLog.LogError("Error on loading texture \"" + valuePair.Key + "\": " + e.Message + e.StackTrace);
}
}
// load videos
- for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++)
+ foreach (var valuePair in _Skins[skinIndex].VideoList)
{
try
{
- xmlReader.GetValue("//root/Videos/" + _Skins[skinIndex].VideoList[i].Name, out value, String.Empty);
- SSkinElement sk = new SSkinElement {Name = _Skins[skinIndex].VideoList[i].Name, Value = value};
- sk.VideoIndex = CVideo.Load(Path.Combine(_Skins[skinIndex].Path, sk.Value));
- CVideo.SetLoop(sk.VideoIndex, true);
- CVideo.Pause(sk.VideoIndex);
- sk.Texture = null;
- _Skins[skinIndex].VideoList[i] = sk;
+ xmlReader.GetValue("//root/Videos/" + valuePair.Key, out valuePair.Value.Value, String.Empty);
}
catch (Exception e)
{
- MessageBox.Show("Error on loading video \"" + _Skins[skinIndex].VideoList[i].Name + "\": " + e.Message + e.StackTrace);
- CLog.LogError("Error on loading video \"" + _Skins[skinIndex].VideoList[i].Name + "\": " + e.Message + e.StackTrace);
+ MessageBox.Show("Error on loading video \"" + valuePair.Key + "\": " + e.Message + e.StackTrace);
+ CLog.LogError("Error on loading video \"" + valuePair.Key + "\": " + e.Message + e.StackTrace);
}
}
@@ -224,37 +212,24 @@ namespace Vocaluxe.Base
public static void UnloadSkins()
{
- int numPartyModeSkins = 0;
for (int i = 0; i < _Skins.Count; i++)
{
- foreach (SSkinElement sk in _Skins[i].SkinList.Values)
- {
- CTexture texture = sk.Texture;
- CDraw.RemoveTexture(ref texture);
- }
+ foreach (var sk in _Skins[i].SkinList.Values)
+ CDraw.RemoveTexture(ref sk.Texture);
- for (int j = 0; j < _Skins[i].VideoList.Count; j++)
+ foreach (var vsk in _Skins[i].VideoList.Values)
{
- CVideo.Close(_Skins[i].VideoList[j].VideoIndex);
- CTexture videoTexture = _Skins[i].VideoList[j].Texture;
- CDraw.RemoveTexture(ref videoTexture);
+ CVideo.Close(vsk.VideoIndex);
+ CDraw.RemoveTexture(ref vsk.Texture);
}
-
- if (_Skins[i].PartyModeID != -1)
- numPartyModeSkins++;
}
- while (_Skins.Count > numPartyModeSkins)
+ for (int i = 0; i < _Skins.Count; i++)
{
- int num = _Skins.Count;
- for (int i = 0; i < num; i++)
- {
- if (_Skins[i].PartyModeID == -1)
- {
- _Skins.RemoveAt(i);
- break;
- }
- }
+ if (_Skins[i].PartyModeID != -1)
+ continue;
+ _Skins.RemoveAt(i);
+ i--;
}
}
@@ -383,16 +358,16 @@ namespace Vocaluxe.Base
#region Skins
writer.WriteStartElement("Skins");
- foreach (SSkinElement element in _Skins[skinIndex].SkinList.Values)
- writer.WriteElementString(element.Name, element.Value);
+ foreach (var element in _Skins[skinIndex].SkinList)
+ writer.WriteElementString(element.Key, element.Value.Value);
writer.WriteEndElement();
#endregion Skins
#region Videos
writer.WriteStartElement("Videos");
- foreach (SSkinElement element in _Skins[skinIndex].VideoList)
- writer.WriteElementString(element.Name, element.Value);
+ foreach (var element in _Skins[skinIndex].VideoList)
+ writer.WriteElementString(element.Key, element.Value.Value);
writer.WriteEndElement();
#endregion Videos
@@ -422,7 +397,7 @@ namespace Vocaluxe.Base
if (xmlReader == null)
return false;
- STheme theme = new STheme();
+ var theme = new STheme();
int version = 0;
xmlReader.TryGetIntValue("//root/ThemeSystemVersion", ref version);
@@ -489,7 +464,7 @@ namespace Vocaluxe.Base
if (xmlReader == null)
continue;
- SSkin skin = new SSkin();
+ var skin = new SSkin();
int version = 0;
xmlReader.TryGetIntValue("//root/SkinSystemVersion", ref version);
@@ -508,21 +483,15 @@ namespace Vocaluxe.Base
skin.FileName = file;
skin.PartyModeID = theme.PartyModeID;
- skin.SkinList = new Dictionary();
+ skin.SkinList = new Dictionary();
List names = xmlReader.GetValues("Skins");
foreach (string str in names)
- {
- SSkinElement sk = new SSkinElement {Name = str, Value = String.Empty};
- skin.SkinList[str] = sk;
- }
+ skin.SkinList[str] = new CSkinElement();
- skin.VideoList = new List();
+ skin.VideoList = new Dictionary();
names = xmlReader.GetValues("Videos");
foreach (string str in names)
- {
- SSkinElement sk = new SSkinElement {Name = str, Value = String.Empty};
- skin.VideoList.Add(sk);
- }
+ skin.VideoList[str] = new CVideoSkinElement();
_Skins.Add(skin);
}
}
@@ -587,8 +556,9 @@ namespace Vocaluxe.Base
public static CTexture GetSkinTexture(string textureName, int partyModeID)
{
int skinIndex = GetSkinIndex(partyModeID);
- if (skinIndex != -1 && textureName != null && _Skins[skinIndex].SkinList.ContainsKey(textureName))
- return _Skins[skinIndex].SkinList[textureName].Texture;
+ CSkinElement sk;
+ if (skinIndex != -1 && textureName != null && _Skins[skinIndex].SkinList.TryGetValue(textureName, out sk))
+ return sk.Texture;
return null;
}
@@ -599,85 +569,57 @@ namespace Vocaluxe.Base
private static string _GetSkinFileName(string skinName, int skinIndex, bool returnPath = false)
{
- foreach (SSkinElement sk in _Skins[skinIndex].SkinList.Values)
- {
- if (sk.Name == skinName)
- return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value);
- }
+ CSkinElement sk;
+ if (_Skins[skinIndex].SkinList.TryGetValue(skinName, out sk))
+ return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value);
CLog.LogError("Can't find Skin Element \"" + skinName);
return skinName;
}
- public static CTexture GetSkinVideoTexture(string videoName, int partyModeID)
+ public static CVideoSkinElement GetSkinVideo(string videoName, int partyModeID, bool load = true)
{
int skinIndex = GetSkinIndex(partyModeID);
if (skinIndex != -1)
{
- for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++)
+ CVideoSkinElement sk;
+ if (_Skins[skinIndex].VideoList.TryGetValue(videoName, out sk))
{
- SSkinElement sk = _Skins[skinIndex].VideoList[i];
- if (sk.Name == videoName)
+ if (sk.VideoIndex == -1 && load)
{
- float time = 0f;
- if (sk.VideoIndex == -1)
- {
- sk.VideoIndex = CVideo.Load(GetVideoFilePath(sk.Name, partyModeID));
- CVideo.SetLoop(sk.VideoIndex, true);
- }
- CVideo.GetFrame(sk.VideoIndex, ref sk.Texture, time, out time);
- _Skins[skinIndex].VideoList[i] = sk;
- return sk.Texture;
+ sk.VideoIndex = CVideo.Load(GetVideoFilePath(videoName, partyModeID));
+ CVideo.SetLoop(sk.VideoIndex, true);
}
+ return sk;
}
}
return null;
}
+ public static CTexture GetSkinVideoTexture(string videoName, int partyModeID)
+ {
+ CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID);
+ if (sk == null)
+ return null;
+ float time = 0f;
+ CVideo.GetFrame(sk.VideoIndex, ref sk.Texture, time, out time);
+ return sk.Texture;
+ }
+
public static void SkinVideoPause(string videoName, int partyModeID)
{
- int skinIndex = GetSkinIndex(partyModeID);
- if (skinIndex != -1)
- {
- for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++)
- {
- SSkinElement sk = _Skins[skinIndex].VideoList[i];
- if (sk.Name == videoName)
- {
- if (sk.VideoIndex == -1)
- {
- sk.VideoIndex = CVideo.Load(GetVideoFilePath(sk.Name, partyModeID));
- CVideo.SetLoop(sk.VideoIndex, true);
- }
- CVideo.Pause(sk.VideoIndex);
- _Skins[skinIndex].VideoList[i] = sk;
- return;
- }
- }
- }
+ CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID, false);
+ if (sk == null)
+ return;
+ CVideo.Pause(sk.VideoIndex);
}
public static void SkinVideoResume(string videoName, int partyModeID)
{
- int skinIndex = GetSkinIndex(partyModeID);
- if (skinIndex != -1)
- {
- for (int i = 0; i < _Skins[skinIndex].VideoList.Count; i++)
- {
- SSkinElement sk = _Skins[skinIndex].VideoList[i];
- if (sk.Name == videoName)
- {
- if (sk.VideoIndex == -1)
- {
- sk.VideoIndex = CVideo.Load(GetVideoFilePath(sk.Name, partyModeID));
- CVideo.SetLoop(sk.VideoIndex, true);
- }
- CVideo.Resume(sk.VideoIndex);
- _Skins[skinIndex].VideoList[i] = sk;
- return;
- }
- }
- }
+ CVideoSkinElement sk = GetSkinVideo(videoName, partyModeID);
+ if (sk == null)
+ return;
+ CVideo.Resume(sk.VideoIndex);
}
public static string GetVideoFilePath(string videoName, int partyModeID)
@@ -687,11 +629,9 @@ namespace Vocaluxe.Base
private static string _GetVideoFileName(string videoName, int skinIndex, bool returnPath = false)
{
- foreach (SSkinElement sk in _Skins[skinIndex].VideoList)
- {
- if (sk.Name == videoName)
- return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value);
- }
+ CVideoSkinElement sk;
+ if (_Skins[skinIndex].VideoList.TryGetValue(videoName, out sk))
+ return !returnPath ? sk.Value : Path.Combine(_Skins[skinIndex].Path, sk.Value);
CLog.LogError("Can't find Video Element \"" + videoName);
return videoName;
@@ -705,13 +645,13 @@ namespace Vocaluxe.Base
if (_Skins[skinIndex].PartyModeID == -1)
{
- List playerColors = new List();
+ var playerColors = new List();
float value = 0f;
int i = 1;
while (xmlReader.TryGetFloatValue("//root/Colors/Player" + i + "/R", ref value))
{
- SColorF color = new SColorF {R = value};
+ var color = new SColorF {R = value};
xmlReader.TryGetFloatValue("//root/Colors/Player" + i + "/G", ref color.G);
xmlReader.TryGetFloatValue("//root/Colors/Player" + i + "/B", ref color.B);
@@ -723,11 +663,11 @@ namespace Vocaluxe.Base
skin.ThemeColors.Player = playerColors.ToArray();
}
- List colorScheme = new List();
+ var colorScheme = new List();
List names = xmlReader.GetValues("ColorSchemes");
foreach (string str in names)
{
- SColorScheme scheme = new SColorScheme {Name = str};
+ var scheme = new SColorScheme {Name = str};
xmlReader.TryGetFloatValue("//root/ColorSchemes/" + str + "/R", ref scheme.Color.R);
xmlReader.TryGetFloatValue("//root/ColorSchemes/" + str + "/G", ref scheme.Color.G);
@@ -790,7 +730,7 @@ namespace Vocaluxe.Base
}
writer.WriteStartElement("ColorSchemes");
- foreach (SColorScheme scheme in _Skins[skinIndex].ThemeColors.ColorSchemes)
+ foreach (var scheme in _Skins[skinIndex].ThemeColors.ColorSchemes)
{
writer.WriteStartElement(scheme.Name);
@@ -840,7 +780,7 @@ namespace Vocaluxe.Base
public static bool GetColor(string colorName, int skinIndex, out SColorF color)
{
- foreach (SColorScheme scheme in _Skins[skinIndex].ThemeColors.ColorSchemes)
+ foreach (var scheme in _Skins[skinIndex].ThemeColors.ColorSchemes)
{
if (scheme.Name == colorName)
{
@@ -856,7 +796,7 @@ namespace Vocaluxe.Base
public static SColorF GetPlayerColor(int playerNr)
{
- SColorF color = new SColorF(1f, 1f, 1f, 1f);
+ var color = new SColorF(1f, 1f, 1f, 1f);
int skinIndex = GetSkinIndex(-1);
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 0ec4f8d3..028c4b2f 100644
--- a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs
+++ b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs
@@ -8,67 +8,54 @@ using VocaluxeLib.Draw;
namespace Vocaluxe.Lib.Video.Acinerella
{
- class CDecoder : IDisposable
+ class CDecoder
{
private IntPtr _Instance = IntPtr.Zero; // acinerella instance
private IntPtr _Videodecoder = IntPtr.Zero; // acinerella video decoder instance
private readonly Stopwatch _LoopTimer = new Stopwatch();
- private Closeproc _Closeproc; // delegate for stream closing
- private int _StreamID; // stream ID for stream closing
- private string _FileName; // current video file name
+ private readonly Thread _Thread;
+ private readonly Object _MutexFramebuffer = new Object();
+ private readonly CFramebuffer _Framebuffer;
+ 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 bool _BufferFull; // buffer is full, waiting for free frame slot
+ private float _FrameDuration; // frame time in s
+ private float _LastDecodedTime; // time of last decoded frame
+ private float _LastShownTime; // current video position
- private bool _Skip; // do skip
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 readonly AutoResetEvent _EvWakeUp = new AutoResetEvent(false);
+ private bool _IsSleeping;
+ private int _WaitCount;
+
+ 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);
+ _Framebuffer = new CFramebuffer(10);
}
- public void Free(Closeproc closeProc, int streamID)
- {
- _Closeproc = closeProc;
- _StreamID = streamID;
- _Terminated = true;
- }
-
- public float Length
- {
- get { return _FileOpened ? _Duration : 0f; }
- }
+ public float Length { get; private set; }
public bool Paused
{
@@ -98,51 +85,56 @@ namespace Vocaluxe.Lib.Video.Acinerella
return false;
_FileName = fileName;
+
+ //Do this here as one may want to get the length afterwards!
+ if (!_DoOpen())
+ return false;
+
+ _FileOpened = true;
+
_Thread.Priority = ThreadPriority.Normal;
_Thread.Name = Path.GetFileName(fileName);
_Thread.Start();
return true;
}
+ public void Close()
+ {
+ _Terminated = true;
+ Length = 0;
+ }
+
public bool GetFrame(ref CTexture frame, float time, out float videoTime)
{
- videoTime = 0;
- if (!_FileOpened)
- return false;
-
if (_Paused)
+ {
+ videoTime = 0;
return false;
+ }
if (Loop)
{
lock (_MutexSyncSignals)
{
_SetTime += _LoopTimer.ElapsedMilliseconds / 1000f;
- videoTime = _SetTime;
-
- _LoopTimer.Stop();
- _LoopTimer.Reset();
- _LoopTimer.Start();
+ _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)
@@ -155,127 +147,108 @@ namespace Vocaluxe.Lib.Video.Acinerella
_NoMoreFrames = false;
Finished = false;
}
- //EventDecode.Set();
return true;
}
#region Threading
- private void _DoSkip()
+ private void _Skip()
{
- if (!_FileOpened)
- return;
-
- _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;
- }
+ _Framebuffer.Clear();
}
- _BufferFull = false;
- _Skip = false;
- _NewFrame = false;
- //EventDecode.Set();
+ _FrameAvailable = false;
}
private void _Execute()
{
- _DoOpen();
- //EventDecode.Set();
while (!_Terminated)
{
+ bool skip;
+ lock (_MutexSyncSignals)
{
- //if (EventDecode.WaitOne(10))
- lock (_MutexSyncSignals)
+ _Time = _SetTime;
+ skip = _SetSkip;
+ _SetSkip = false;
+ _Gap = _SetGap;
+ _Start = _SetStart;
+ _Loop = Loop;
+ }
+
+ if (skip)
+ _Skip();
+
+ if (!_FrameAvailable)
+ _Decode();
+
+ if (_FrameAvailable)
+ {
+ if (!_Framebuffer.IsFull())
{
- _Time = _SetTime;
- if (_SetSkip)
- _Skip = true;
-
- _SetSkip = false;
- _Gap = _SetGap;
- _Start = _SetStart;
- _Loop = Loop;
- }
-
- if (_Skip)
- _DoSkip();
-
- if (!_NewFrame)
- _DoDecode();
-
- if (_NewFrame)
_Copy();
- Thread.Sleep(1);
+ _WaitCount = 0;
+ Thread.Sleep(1);
+ }
+ else if (_WaitCount > 3)
+ {
+ _IsSleeping = true;
+ _EvWakeUp.WaitOne();
+ }
+ else
+ {
+ Thread.Sleep((int)((_Framebuffer.Size - 2) * _FrameDuration * 1000));
+ _WaitCount++;
+ }
}
}
- _DoFree();
+ _Free();
}
- private void _DoOpen()
+ private bool _DoOpen()
{
bool ok;
- SACInstance instance = new SACInstance();
try
{
_Instance = CAcinerella.AcInit();
CAcinerella.AcOpen2(_Instance, _FileName);
- instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance));
+ var instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance));
+ Length = instance.Info.Duration / 1000f;
ok = instance.Opened;
}
catch (Exception)
{
- CLog.LogError("Error opening video file: " + _FileName);
ok = false;
}
-
- if (!instance.Opened || !ok)
+ if (!ok)
{
- //Free();
- return;
+ CLog.LogError("Error opening video file: " + _FileName);
+ return false;
}
- _Duration = instance.Info.Duration / 1000f;
-
int videoStreamIndex;
SACDecoder videodecoder;
try
@@ -287,61 +260,73 @@ namespace Vocaluxe.Lib.Video.Acinerella
catch (Exception)
{
CLog.LogError("Error opening video file (can't find decoder): " + _FileName);
- return;
+ _Free();
+ return false;
}
-
if (videoStreamIndex < 0)
{
- //Free();
- return;
+ _Free();
+ return false;
}
_Width = videodecoder.StreamInfo.VideoInfo.FrameWidth;
_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;
- _Time = 0f;
+ _LastDecodedTime = 0f;
+ _SetTime = 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];
- }
- _FileOpened = true;
+ _Framebuffer.Init(_Width * _Height * 4);
+ _FrameAvailable = false;
+ return true;
}
- private void _DoDecode()
+ private void _Decode()
{
- const int framedropcount = 4;
+ const int minFrameDropCount = 4;
- if (!_FileOpened || _NewFrame)
+ if (_Paused || _NoMoreFrames)
return;
- if (_Paused || _NoMoreFrames || _BufferFull)
- return;
+ float videoTime = _Time + _Gap;
+ float timeDifference = videoTime - _LastDecodedTime;
- if ((_SkipTime < 0f) && (_Time + _SkipTime >= 0f))
- _SkipTime = 0f;
-
- float myTime = _Time + _VideoSkipTime;
- float timeDifference = myTime - _VideoDecoderTime;
-
- bool dropFrame = timeDifference >= (framedropcount - 1) * _VideoTimeBase;
+ bool dropFrame = timeDifference >= (minFrameDropCount - 1) * _FrameDuration;
if (_Terminated)
return;
- int frameFinished = 0;
- if (dropFrame && !_BeforeLoop)
+ bool frameFinished = false;
+ if (dropFrame)
{
try
{
- frameFinished = CAcinerella.AcSkipFrames(_Instance, _Videodecoder, framedropcount - 1);
+ if (videoTime >= Length)
+ {
+ if (_Loop)
+ {
+ lock (_MutexSyncSignals)
+ {
+ _Start = 0;
+ _Gap = 0f;
+ _SetTime = 0;
+ }
+ _Skip();
+ }
+ else
+ {
+ _NoMoreFrames = true;
+ return;
+ }
+ }
+ else
+ {
+ var frameDropCount = (int)(timeDifference / _FrameDuration);
+ frameFinished = CAcinerella.AcSkipFrames(_Instance, _Videodecoder, frameDropCount);
+ }
}
catch (Exception)
{
@@ -349,7 +334,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
}
}
- if (!_BeforeLoop && (!dropFrame || frameFinished != 0))
+ if (!frameFinished)
{
try
{
@@ -360,171 +345,97 @@ 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;
}
-
- _DoSkip();
+ _Skip();
}
else
_NoMoreFrames = true;
}
- else
- {
- _NewFrame = true;
- _Copy();
- }
}
private void _Copy()
{
- if (!_NewFrame)
+ var videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder));
+ if (videodecoder.Buffer == IntPtr.Zero)
return;
-
- int num = -1;
-
- lock (_MutexFramebuffer)
- {
- for (int i = 0; i < _FrameBuffer.Length; i++)
- {
- if (_FrameBuffer[i].Displayed)
- {
- num = i;
- break;
- }
- }
-
- if (num == -1)
- _BufferFull = true;
- else
- {
- SACDecoder videodecoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder));
-
- _VideoDecoderTime = (float)videodecoder.Timecode;
- _FrameBuffer[num].Time = _VideoDecoderTime;
-
- 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++)
- {
- if (!_FrameBuffer[i].Displayed)
- numfull++;
- }
-
- if (numfull < _FrameBuffer.Length)
- _BufferFull = false;
-
- _NewFrame = false;
- }
- }
+ _LastDecodedTime = (float)videodecoder.Timecode;
+ _Framebuffer.Put(videodecoder.Buffer, _LastDecodedTime);
+ _FrameAvailable = false;
}
private void _UploadNewFrame(ref CTexture frame)
{
- if (!_FileOpened)
- return;
-
lock (_MutexFramebuffer)
{
- int num = _FindFrame();
+ CFrame curFrame = _FindFrame();
- if (num >= 0)
+ if (curFrame != null)
{
- CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _FrameBuffer[num].Data);
+ CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, curFrame.Data);
lock (_MutexSyncSignals)
{
- _CurrentVideoTime = _FrameBuffer[num].Time;
+ _LastShownTime = curFrame.Time;
}
- Finished = false;
}
else
{
- if (_NoMoreFrames)
+ if (_NoMoreFrames && _Framebuffer.IsEmpty())
Finished = true;
}
}
+ if (!Finished && _IsSleeping)
+ {
+ _IsSleeping = false;
+ _EvWakeUp.Set();
+ }
}
- private int _FindFrame()
+ private CFrame _FindFrame()
{
- int result = -1;
- float diff = 10000000f;
-
- for (int i = 0; i < _FrameBuffer.Length; i++)
+ CFrame result = null;
+ float now = _SetTime + _Gap;
+ float maxEnd = now - _FrameDuration * 2; //Get only frames younger than 2
+ CFrame frame;
+ while ((frame = _Framebuffer.Get()) != null)
{
- float td = _SetTime + _VideoSkipTime - _FrameBuffer[i].Time;
+ float frameEnd = frame.Time + _FrameDuration;
+ //Don't show frames that are shown during or after now
+ if (frameEnd >= now)
+ break; //All following frames are after that one
- if (td > _VideoTimeBase * 2f)
- _FrameBuffer[i].Displayed = true;
-
- if (!_FrameBuffer[i].Displayed && (td < diff) && (td > _VideoTimeBase))
- {
- diff = Math.Abs(_FrameBuffer[i].Time - _SetTime - _VideoSkipTime);
- result = i;
- }
+ _Framebuffer.SetRead();
+ //Get the last(newest) possible frame and skip the rest to force in-order showing
+ if (frameEnd <= maxEnd)
+ continue;
+ maxEnd = frameEnd;
+ result = frame;
}
-
- if (result != -1)
- {
- _FrameBuffer[result].Displayed = true;
- _BufferFull = false;
- }
-
return result;
}
- private void _DoFree()
+ private void _Free()
{
if (_Videodecoder != IntPtr.Zero)
CAcinerella.AcFreeDecoder(_Videodecoder);
if (_Instance != IntPtr.Zero)
+ {
CAcinerella.AcClose(_Instance);
-
- if (_Instance != IntPtr.Zero)
CAcinerella.AcFree(_Instance);
-
- _Closeproc(_StreamID);
+ }
}
#endregion Threading
-
- public void Dispose() {}
}
}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Video/Acinerella/CFramebuffer.cs b/Vocaluxe/Lib/Video/Acinerella/CFramebuffer.cs
new file mode 100644
index 00000000..8aaa6287
--- /dev/null
+++ b/Vocaluxe/Lib/Video/Acinerella/CFramebuffer.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Vocaluxe.Lib.Video.Acinerella
+{
+ class CFrame
+ {
+ public readonly byte[] Data;
+ public float Time = -1;
+
+ public CFrame(int dataSize)
+ {
+ Data = new byte[dataSize];
+ }
+ }
+
+ class CFramebuffer
+ {
+ private readonly CFrame[] _Frames;
+ private readonly int _Size;
+ private int _DataSize;
+ private int _Last;
+ private int _First;
+ private bool _Initialized;
+
+ public int Size
+ {
+ get { return _Size; }
+ }
+
+ public CFramebuffer(int size)
+ {
+ _Size = size;
+ _Frames = new CFrame[size];
+ }
+
+ public void Init(int dataSize)
+ {
+ _DataSize = dataSize;
+ for (int i = 0; i < _Size; i++)
+ _Frames[i] = new CFrame(dataSize);
+ _Initialized = true;
+ }
+
+ private int _Next(int current)
+ {
+ current++;
+ return (current < _Size) ? current : 0;
+ }
+
+ public bool IsFull()
+ {
+ return _Next(_Last) == _First;
+ }
+
+ public bool IsEmpty()
+ {
+ return _First == _Last;
+ }
+
+ public bool Put(IntPtr data, float time)
+ {
+ if (!_Initialized || IsFull())
+ return false;
+ CFrame frame = _Frames[_Last];
+ Marshal.Copy(data, frame.Data, 0, _DataSize);
+ frame.Time = time;
+ _Last = _Next(_Last);
+ return true;
+ }
+
+ public CFrame Get()
+ {
+ return IsEmpty() ? null : _Frames[_First];
+ }
+
+ public bool SetRead()
+ {
+ if (IsEmpty())
+ return false;
+ _First = _Next(_First);
+ return true;
+ }
+
+ public void Clear()
+ {
+ _First = 0;
+ _Last = 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Video/CVideoDecoder.cs b/Vocaluxe/Lib/Video/CVideoDecoder.cs
deleted file mode 100644
index 79ea8b52..00000000
--- a/Vocaluxe/Lib/Video/CVideoDecoder.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-#region license
-// /*
-// This file is part of Vocaluxe.
-//
-// Vocaluxe is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Vocaluxe is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Vocaluxe. If not, see .
-// */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using VocaluxeLib.Draw;
-
-namespace Vocaluxe.Lib.Video
-{
- abstract class CVideoDecoder : IVideoDecoder
- {
- protected List _Streams = new List();
- protected bool _Initialized;
-
- public virtual bool Init()
- {
- _Streams = new List();
- _Initialized = true;
-
- return true;
- }
-
- public abstract void CloseAll();
-
- public virtual int GetNumStreams()
- {
- return _Streams.Count;
- }
-
- public virtual int Load(string videoFileName)
- {
- return 0;
- }
-
- public virtual bool Close(int streamID)
- {
- return true;
- }
-
- public virtual float GetLength(int streamID)
- {
- return 0f;
- }
-
- public abstract bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime);
-
- public virtual bool Skip(int streamID, float start, float gap)
- {
- return true;
- }
-
- public virtual void SetLoop(int streamID, bool loop) {}
-
- public virtual void Pause(int streamID) {}
-
- public virtual void Resume(int streamID) {}
-
- public virtual bool Finished(int streamID)
- {
- return false;
- }
-
- public virtual void Update() {}
-
- protected bool _AlreadyAdded(int streamID)
- {
- return _Streams.Any(st => st.Handle == streamID);
- }
-
- protected int _GetStreamIndex(int streamID)
- {
- for (int i = 0; i < _Streams.Count; i++)
- {
- if (_Streams[i].Handle == streamID)
- return i;
- }
- return -1;
- }
- }
-}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
index 000181f4..85d9b25c 100644
--- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
+++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
@@ -17,184 +17,114 @@
// */
#endregion
-using System;
using System.Collections.Generic;
using Vocaluxe.Lib.Video.Acinerella;
using VocaluxeLib.Draw;
namespace Vocaluxe.Lib.Video
{
- delegate void Closeproc(int streamID);
-
- class CVideoDecoderFFmpeg : CVideoDecoder
+ class CVideoDecoderFFmpeg : IVideoDecoder
{
- private readonly List _Decoder = new List();
- private Closeproc _Closeproc;
- private int _Count = 1;
+ private readonly Dictionary _Decoder = new Dictionary();
+ private int _LastID;
- private readonly Object _MutexDecoder = new Object();
-
- public override bool Init()
+ public bool Init()
{
- _Closeproc = _CloseProc;
CloseAll();
-
- return base.Init();
+ return true;
}
- public override void CloseAll()
+ public void CloseAll()
{
- lock (_MutexDecoder)
- {
- for (int i = 0; i < _Decoder.Count; i++)
- _Decoder[i].Free(_Closeproc, i + 1);
- }
+ foreach (var decoder in _Decoder.Values)
+ decoder.Close();
+ _Decoder.Clear();
}
- public override int Load(string videoFileName)
+ public int Load(string videoFileName)
{
- SVideoStreams stream = new SVideoStreams(0);
- CDecoder decoder = new CDecoder();
+ var decoder = new CDecoder();
if (decoder.Open(videoFileName))
{
- lock (_MutexDecoder)
- {
- _Decoder.Add(decoder);
- stream.Handle = _Count++;
- _Streams.Add(stream);
- return stream.Handle;
- }
+ int id = _LastID++;
+ _Decoder.Add(id, decoder);
+ return id;
}
return -1;
}
- public override bool Close(int streamID)
+ public bool Close(int streamID)
{
- if (_Initialized)
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
{
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- {
- _Decoder[_GetStreamIndex(streamID)].Free(_Closeproc, streamID);
- return true;
- }
- }
+ decoder.Close();
+ _Decoder.Remove(streamID);
+ return true;
}
return false;
}
- public override bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime)
+ public int GetNumStreams()
{
+ return _Decoder.Count;
+ }
+
+ public bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime)
+ {
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ return decoder.GetFrame(ref frame, time, out videoTime);
videoTime = 0;
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- return _Decoder[_GetStreamIndex(streamID)].GetFrame(ref frame, time, out videoTime);
- }
- }
return false;
}
- public override float GetLength(int streamID)
+ public float GetLength(int streamID)
{
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- return _Decoder[_GetStreamIndex(streamID)].Length;
- }
- }
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ return decoder.Length;
return 0f;
}
- public override bool Skip(int streamID, float start, float gap)
+ public bool Skip(int streamID, float start, float gap)
{
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- return _Decoder[_GetStreamIndex(streamID)].Skip(start, gap);
- }
- }
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ return decoder.Skip(start, gap);
return false;
}
- public override void SetLoop(int streamID, bool loop)
+ public void SetLoop(int streamID, bool loop)
{
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- _Decoder[_GetStreamIndex(streamID)].Loop = loop;
- }
- }
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ decoder.Loop = loop;
}
- public override void Pause(int streamID)
+ public void Pause(int streamID)
{
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- _Decoder[_GetStreamIndex(streamID)].Paused = true;
- }
- }
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ decoder.Paused = true;
}
- public override void Resume(int streamID)
+ public void Resume(int streamID)
{
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- _Decoder[_GetStreamIndex(streamID)].Paused = false;
- }
- }
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ decoder.Paused = false;
}
- public override bool Finished(int streamID)
+ public bool Finished(int streamID)
{
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- return _Decoder[_GetStreamIndex(streamID)].Finished;
- }
- }
+ CDecoder decoder;
+ if (_Decoder.TryGetValue(streamID, out decoder))
+ return decoder.Finished;
return true;
}
- private void _CloseProc(int streamID)
- {
- if (_Initialized)
- {
- lock (_MutexDecoder)
- {
- if (_AlreadyAdded(streamID))
- {
- int index = _GetStreamIndex(streamID);
- _Decoder.RemoveAt(index);
- _Streams.RemoveAt(index);
- }
- }
- }
- }
- }
-
- struct SFrameBuffer
- {
- public byte[] Data;
- public float Time;
- public bool Displayed;
+ public void Update() {}
}
}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Video/IVideoDecoder.cs b/Vocaluxe/Lib/Video/IVideoDecoder.cs
index 39b54587..6c48a24e 100644
--- a/Vocaluxe/Lib/Video/IVideoDecoder.cs
+++ b/Vocaluxe/Lib/Video/IVideoDecoder.cs
@@ -21,16 +21,6 @@ using VocaluxeLib.Draw;
namespace Vocaluxe.Lib.Video
{
- struct SVideoStreams
- {
- public int Handle;
-
- public SVideoStreams(int stream)
- {
- Handle = stream;
- }
- }
-
interface IVideoDecoder
{
bool Init();
diff --git a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs
index 6184d583..1856b90d 100644
--- a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs
+++ b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs
@@ -54,10 +54,7 @@ namespace Vocaluxe.Screens
set
{
_VideoPreviewInt = value;
- if (!_VideoPreviewInt && !_VideoBackground)
- CBackgroundMusic.VideoEnabled = false;
- else
- CBackgroundMusic.VideoEnabled = true;
+ CBackgroundMusic.VideoEnabled = _VideoPreviewInt || _VideoBackground;
}
}
diff --git a/Vocaluxe/Screens/CScreenOptionsVideo.cs b/Vocaluxe/Screens/CScreenOptionsVideo.cs
index 04b1ef16..71c11d97 100644
--- a/Vocaluxe/Screens/CScreenOptionsVideo.cs
+++ b/Vocaluxe/Screens/CScreenOptionsVideo.cs
@@ -221,7 +221,7 @@ namespace Vocaluxe.Screens
CConfig.VideosToBackground = (EOffOn)_SelectSlides[_SelectSlideVideosToBackground].Selection;
CConfig.WebcamConfig = _Config;
- CBackgroundMusic.VideoEnabled = true;
+ CBackgroundMusic.VideoEnabled = CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON;
CConfig.SaveConfig();
}
diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj
index ff72492f..2360607d 100644
--- a/Vocaluxe/Vocaluxe.csproj
+++ b/Vocaluxe/Vocaluxe.csproj
@@ -217,6 +217,7 @@
+
@@ -248,7 +249,6 @@
-
diff --git a/VocaluxeLib/Menu/CMenu.cs b/VocaluxeLib/Menu/CMenu.cs
index 3de37a98..4a3021b9 100644
--- a/VocaluxeLib/Menu/CMenu.cs
+++ b/VocaluxeLib/Menu/CMenu.cs
@@ -137,7 +137,7 @@ namespace VocaluxeLib.Menu
_ThemeScreenSettings = null;
}
- protected void _FadeTo(EScreens nextScreen)
+ protected static void _FadeTo(EScreens nextScreen)
{
CBase.Graphics.FadeTo(nextScreen);
}
diff --git a/VocaluxeLib/Menu/CMenuParty.cs b/VocaluxeLib/Menu/CMenuParty.cs
index 965f6175..d57a9304 100644
--- a/VocaluxeLib/Menu/CMenuParty.cs
+++ b/VocaluxeLib/Menu/CMenuParty.cs
@@ -36,7 +36,7 @@ namespace VocaluxeLib.Menu
_PartyModeID = partyModeID;
}
- public void AssingPartyMode(IPartyMode partyMode)
+ public void AssignPartyMode(IPartyMode partyMode)
{
_PartyMode = partyMode;
}