internal bool CheckIfAnyDirectOrIndirectTransitionIsPossible(Soundtrack soundtrack, int targetThemeId) { if (CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetThemeId) == true) { return(true); } else { return(MapOfNextTransitionSegmentToTheme.ContainsKey(targetThemeId)); } }
/* This method is responsible to link each Segment of a Theme to the Target Theme * in the shortest path possible. If multiple compatible Segments exist, the one with the * best-matching intensity will be chosen. * After the algorithm has finished, each Snippet's _mapCompatibleSegmentsToTheme will hold * the Segment to be played next when a Theme Transition is in progress, or NULL * if either no transition is possible at all, or if a direct transition is possible. */ internal void BuildSequencesToTargetThemeForAllSegments(Soundtrack soundtrack, Theme targetTheme) { foreach (Segment snippet in m_segments) { snippet.MapOfNextTransitionSegmentToTheme.Remove(targetTheme.id); } List <Segment> snippetsAddedInLastTier = new List <Segment>(); foreach (Segment snippet in m_segments) { if (snippet.CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetTheme.id) == true) { snippetsAddedInLastTier.Add(snippet); } } SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList(snippetsAddedInLastTier.ToArray(), soundtrack, targetTheme); #if !(PSAI_NOLOG) { if (LogLevel.debug <= Logger.Instance.LogLevel) { StringBuilder sb = new StringBuilder(); sb.Append("BuildSequencesToTargetThemeForAllSegments completed for Theme "); sb.Append(this); sb.Append(" to Theme "); sb.Append(targetTheme); sb.Append("\n"); foreach (Segment snippet in m_segments) { sb.Append(snippet); sb.Append(" -> "); if (snippet.MapOfNextTransitionSegmentToTheme.ContainsKey(targetTheme.id) == false) { sb.Append(" DirectTransition:"); sb.Append(snippet.CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetTheme.id)); } else { sb.Append(snippet.MapOfNextTransitionSegmentToTheme[targetTheme.id].ToString()); } sb.Append("\n"); } Logger.Instance.Log(sb.ToString(), LogLevel.debug); } } #endif }
// returns true if the theme with the given themeId contains at least one Segment // that would be a compatible follower / layer of the Segment with the given snippetId. // Ignores the Suitabilities of both the Source and Target Segments. public bool CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(Soundtrack soundtrack, int targetThemeId) { if (_mapDirectTransitionToThemeIsPossible.ContainsKey(targetThemeId)) { return(_mapDirectTransitionToThemeIsPossible[targetThemeId]); } else { foreach (Follower follower in Followers) { Segment followerSnippet = soundtrack.GetSegmentById(follower.snippetId); if (followerSnippet.ThemeId == targetThemeId) { _mapDirectTransitionToThemeIsPossible[targetThemeId] = true; return(true); } } } _mapDirectTransitionToThemeIsPossible[targetThemeId] = false; return(false); }
private PsaiResult Readfile_ProtoBuf(System.IO.Stream stream) { if (stream == null) { return PsaiResult.file_notFound; } else { m_soundtrack.Clear(); m_themeQueue.Clear(); psai.ProtoBuf_PsaiCoreSoundtrack pbSoundtrack; try { pbSoundtrack = ProtoBuf.Serializer.Deserialize<psai.ProtoBuf_PsaiCoreSoundtrack>(stream); } catch (System.Exception ex) { Logger.Instance.Log(ex.Message, LogLevel.errors); return PsaiResult.error_file; } //m_protobufAudioFormatString = pbSoundtrack.audioformat; m_soundtrack = new Soundtrack(pbSoundtrack); return PsaiResult.OK; } }
internal PsaiResult LoadSoundtrack(string pathToPcbFile) { m_psaiCoreBinaryFilepath = pathToPcbFile; m_psaiCoreBinaryDirectoryName = Path.GetDirectoryName(m_psaiCoreBinaryFilepath); m_initializationFailure = false; m_soundtrack = new Soundtrack(); PsaiResult psaiResultReadfile = PsaiResult.none; using (Stream stream = m_platformLayer.GetStreamOnPsaiCoreBinary(m_psaiCoreBinaryFilepath)) { psaiResultReadfile = Readfile_ProtoBuf(stream); if (psaiResultReadfile != PsaiResult.OK) { #if !(PSAI_NOLOG) Logger.Instance.Log("failed to load Soundtrack! error=" + psaiResultReadfile, LogLevel.errors); #endif return psaiResultReadfile; } else { #if !(PSAI_NOLOG) Logger.Instance.Log("Soundtrack deserialization succeeded", LogLevel.info); #endif } } InitMembersAfterSoundtrackHasLoaded(); return PsaiResult.OK; }
public PsaiResult LoadSoundtrackByPsaiProject(psai.Editor.PsaiProject psaiProject, string fullProjectPath) { m_soundtrack = psaiProject.BuildPsaiDotNetSoundtrackFromProject(); m_psaiCoreBinaryFilepath = fullProjectPath; m_psaiCoreBinaryDirectoryName = Path.GetDirectoryName(fullProjectPath); InitMembersAfterSoundtrackHasLoaded(); #if !(PSAI_NOLOG) { if (LogLevel.info <= Logger.Instance.LogLevel) { Logger.Instance.Log("Soundtrack deserialization succeeded", LogLevel.info); } } #endif return PsaiResult.OK; }
internal Logik() { #if PSAI_STANDALONE m_platformLayer = new PlatformLayerStandalone(this); #else m_platformLayer = new PlatformLayerUnity(); #endif m_platformLayer.Initialize(); m_soundtrack = new Soundtrack(); m_themeQueue = new List<ThemeQueueEntry>(); m_fadeVoices = new List<FadeData>(); for (int i = 0; i < PSAI_CHANNEL_COUNT; i++) { m_playbackChannels[i] = new PlaybackChannel(); } m_hilightVoiceIndex = -1; m_lastRegularVoiceNumberReturned = -1; m_currentVoiceNumber = -1; m_targetVoice = -1; m_psaiMasterVolume = 1.0f; m_effectiveTheme = null; m_currentSegmentPlaying = null; m_currentSnippetTypeRequested = 0; m_targetSegment = null; m_targetSegmentSuitabilitiesRequested = 0; m_psaiState = PsaiState.notready; m_psaiStateIntended = PsaiState.notready; m_paused = false; m_fullVersionString = "psai Version " + PSAI_VERSION; #if !(PSAI_NOLOG) Logger.Instance.LogLevel = LogLevel.info; Logger.Instance.Log(m_fullVersionString, LogLevel.info); #endif s_instance = this; }
/** * @param listOfSnippetsWithValidTransitionSequencesToTargetTheme - a list of Snippets that have a valid Transition-Sequence to or directly compatible followers in a given TargetTheme. */ private void SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList(Segment[] listOfSnippetsWithValidTransitionSequencesToTargetTheme, Soundtrack soundtrack, Theme targetTheme) { /* #if !(PSAI_NOLOG) * if (LogLevel.debug <= Logger.Instance.LogLevel) * { * Logger.Instance.Log("SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList() called, listOfSnippets.Length=" + listOfSnippetsWithValidEndSequences.Length, LogLevel.debug); * StringBuilder sb = new StringBuilder(); * foreach (Snippet argSnippet in listOfSnippetsWithValidEndSequences) * { * sb.Append(argSnippet.name); * sb.Append(" intensity="); * sb.Append(argSnippet.intensity); * sb.Append(" nextSnippetToShEndSeq="); * sb.Append(argSnippet.nextSnippetToShortestEndSequence); * sb.Append(" "); * } * Logger.Instance.Log(sb.ToString(), LogLevel.debug); * } #endif */ Dictionary <Segment, List <Segment> > mapWaypointAlternativesForSnippet = new Dictionary <Segment, List <Segment> >(); foreach (Segment transitionSnippet in listOfSnippetsWithValidTransitionSequencesToTargetTheme) { List <Segment> sourceSnippets = GetSetOfAllSourceSegmentsCompatibleToSegment(transitionSnippet, Logik.COMPATIBILITY_PERCENTAGE_SAME_GROUP, SegmentSuitability.none); sourceSnippets.Remove(transitionSnippet); foreach (Segment sourceSnippet in sourceSnippets) { if (sourceSnippet.MapOfNextTransitionSegmentToTheme.ContainsKey(targetTheme.id) == false && sourceSnippet.CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetTheme.id) == false && sourceSnippet.ThemeId == transitionSnippet.ThemeId) { if (mapWaypointAlternativesForSnippet.ContainsKey(sourceSnippet) == false) { mapWaypointAlternativesForSnippet[sourceSnippet] = new List <Segment>(); } mapWaypointAlternativesForSnippet[sourceSnippet].Add(transitionSnippet); } } } foreach (Segment snippet in mapWaypointAlternativesForSnippet.Keys) { snippet.MapOfNextTransitionSegmentToTheme[targetTheme.id] = snippet.ReturnSegmentWithLowestIntensityDifference(mapWaypointAlternativesForSnippet[snippet]); } Segment[] snippetsAdded = new Segment[mapWaypointAlternativesForSnippet.Count]; mapWaypointAlternativesForSnippet.Keys.CopyTo(snippetsAdded, 0); if (snippetsAdded.Length > 0) { SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList(snippetsAdded, soundtrack, targetTheme); } }
/** * @param listOfSnippetsWithValidTransitionSequencesToTargetTheme - a list of Snippets that have a valid Transition-Sequence to or directly compatible followers in a given TargetTheme. */ private void SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList(Segment[] listOfSnippetsWithValidTransitionSequencesToTargetTheme, Soundtrack soundtrack, Theme targetTheme) { /* #if !(PSAI_NOLOG) if (LogLevel.debug <= Logger.Instance.LogLevel) { Logger.Instance.Log("SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList() called, listOfSnippets.Length=" + listOfSnippetsWithValidEndSequences.Length, LogLevel.debug); StringBuilder sb = new StringBuilder(); foreach (Snippet argSnippet in listOfSnippetsWithValidEndSequences) { sb.Append(argSnippet.name); sb.Append(" intensity="); sb.Append(argSnippet.intensity); sb.Append(" nextSnippetToShEndSeq="); sb.Append(argSnippet.nextSnippetToShortestEndSequence); sb.Append(" "); } Logger.Instance.Log(sb.ToString(), LogLevel.debug); } #endif */ Dictionary<Segment, List<Segment>> mapWaypointAlternativesForSnippet = new Dictionary<Segment, List<Segment>>(); foreach (Segment transitionSnippet in listOfSnippetsWithValidTransitionSequencesToTargetTheme) { List<Segment> sourceSnippets = GetSetOfAllSourceSegmentsCompatibleToSegment(transitionSnippet, Logik.COMPATIBILITY_PERCENTAGE_SAME_GROUP, SegmentSuitability.none); sourceSnippets.Remove(transitionSnippet); foreach (Segment sourceSnippet in sourceSnippets) { if (sourceSnippet.MapOfNextTransitionSegmentToTheme.ContainsKey(targetTheme.id) == false && sourceSnippet.CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetTheme.id) == false && sourceSnippet.ThemeId == transitionSnippet.ThemeId) { if (mapWaypointAlternativesForSnippet.ContainsKey(sourceSnippet) == false) { mapWaypointAlternativesForSnippet[sourceSnippet] = new List<Segment>(); } mapWaypointAlternativesForSnippet[sourceSnippet].Add(transitionSnippet); } } } foreach (Segment snippet in mapWaypointAlternativesForSnippet.Keys) { snippet.MapOfNextTransitionSegmentToTheme[targetTheme.id] = snippet.ReturnSegmentWithLowestIntensityDifference(mapWaypointAlternativesForSnippet[snippet]); } Segment[] snippetsAdded = new Segment[mapWaypointAlternativesForSnippet.Count]; mapWaypointAlternativesForSnippet.Keys.CopyTo(snippetsAdded, 0); if (snippetsAdded.Length > 0) { SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList(snippetsAdded, soundtrack, targetTheme); } }
/* This method is responsible to link each Segment of a Theme to the Target Theme * in the shortest path possible. If multiple compatible Segments exist, the one with the * best-matching intensity will be chosen. * After the algorithm has finished, each Snippet's _mapCompatibleSegmentsToTheme will hold * the Segment to be played next when a Theme Transition is in progress, or NULL * if either no transition is possible at all, or if a direct transition is possible. */ internal void BuildSequencesToTargetThemeForAllSegments(Soundtrack soundtrack, Theme targetTheme) { foreach (Segment snippet in m_segments) { snippet.MapOfNextTransitionSegmentToTheme.Remove(targetTheme.id); } List<Segment> snippetsAddedInLastTier = new List<Segment>(); foreach (Segment snippet in m_segments) { if (snippet.CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetTheme.id) == true) { snippetsAddedInLastTier.Add(snippet); } } SetTheNextSegmentToShortestTransitionSequenceToTargetThemeForAllSourceSegmentsOfTheSegmentsInThisList(snippetsAddedInLastTier.ToArray(), soundtrack, targetTheme); #if !(PSAI_NOLOG) { if (LogLevel.debug <= Logger.Instance.LogLevel) { StringBuilder sb = new StringBuilder(); sb.Append("BuildSequencesToTargetThemeForAllSegments completed for Theme "); sb.Append(this); sb.Append(" to Theme "); sb.Append(targetTheme); sb.Append("\n"); foreach (Segment snippet in m_segments) { sb.Append(snippet); sb.Append(" -> "); if (snippet.MapOfNextTransitionSegmentToTheme.ContainsKey(targetTheme.id) == false) { sb.Append(" DirectTransition:"); sb.Append(snippet.CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetTheme.id)); } else { sb.Append(snippet.MapOfNextTransitionSegmentToTheme[targetTheme.id].ToString()); } sb.Append("\n"); } Logger.Instance.Log(sb.ToString(), LogLevel.debug); } } #endif }
internal bool CheckIfAnyDirectOrIndirectTransitionIsPossible(Soundtrack soundtrack, int targetThemeId) { if (CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(soundtrack, targetThemeId) == true) { return true; } else { return MapOfNextTransitionSegmentToTheme.ContainsKey(targetThemeId); } }
// returns true if the theme with the given themeId contains at least one Segment // that would be a compatible follower / layer of the Segment with the given snippetId. // Ignores the Suitabilities of both the Source and Target Segments. public bool CheckIfAtLeastOneDirectTransitionOrLayeringIsPossible(Soundtrack soundtrack, int targetThemeId) { if (_mapDirectTransitionToThemeIsPossible.ContainsKey(targetThemeId)) { return _mapDirectTransitionToThemeIsPossible[targetThemeId]; } else { foreach (Follower follower in Followers) { Segment followerSnippet = soundtrack.GetSegmentById(follower.snippetId); if (followerSnippet.ThemeId == targetThemeId) { _mapDirectTransitionToThemeIsPossible[targetThemeId] = true; return true; } } } _mapDirectTransitionToThemeIsPossible[targetThemeId] = false; return false; }