public static ProcessResultArray <Clip> Apply(Command command, ClipMetaData metadata, params Clip[] clips) { var(success, msg) = OptionParser.TryParseOptions(command, out InterleaveOptions options); if (!success) { return(new ProcessResultArray <Clip>(msg)); } return(Apply(options, metadata, clips)); }
public static ProcessResultArray <Clip> Apply(Command command, ClipMetaData metadata, Clip[] clips, InterleaveMode mode) { var(success, msg) = OptionParser.TryParseOptions(command, out InterleaveOptions options); if (!success) { return(new ProcessResultArray <Clip>(msg)); } if (mode != NotSpecified) { options.Mode = mode; } return(Apply(options, metadata, clips)); }
public static ProcessResult <ChainedCommand> ParseFormulaToChainedCommand(string formula, List <Clip> clips, ClipMetaData metadata) { var valid = new char[] { '[', ']' }.All(c => formula.IndexOf(c) >= 0); if (!valid) { return(new ProcessResult <ChainedCommand>($"Invalid formula: {formula}")); } var lexer = new Lexer(formula, clips); var result = lexer.GetTokens(); if (!result.Success) { return(new ProcessResult <ChainedCommand>(result.ErrorMessage)); } var resolvedTokens = ResolveOperators(result.Result); if (!resolvedTokens.Success) { return(new ProcessResult <ChainedCommand>(resolvedTokens.ErrorMessage)); } Token[] commandTokens = resolvedTokens.Result; var commandTokensLists = new List <List <Token> >(); var activeCommandTokenList = new List <Token>(); var sourceClips = commandTokens.TakeWhile(x => x.Type == TokenType.InlineClip).Select(x => x.Clip).ToArray(); var tokensToProcess = commandTokens.Skip(sourceClips.Count()).ToArray(); if (tokensToProcess.Length == 0) { // Empty command, assume concat tokensToProcess = new Token[] { new Token(TokenType.Concat, "concat", 0), }; } foreach (var token in tokensToProcess) { if (token.IsCommand) { if (activeCommandTokenList.Count == 0) { activeCommandTokenList.Add(token); } else { commandTokensLists.Add(activeCommandTokenList); activeCommandTokenList = new List <Token> { token }; } } else { activeCommandTokenList.Add(token); } } commandTokensLists.Add(activeCommandTokenList); // add last command token list var commands = commandTokensLists.Select(ParseTokensToCommand).ToList(); var chainedCommand = new ChainedCommand(commands, sourceClips, metadata); return(new ProcessResult <ChainedCommand>(chainedCommand)); }
public static ProcessResultArray <Clip> ProcessCommand(Command command, Clip[] incomingClips, ClipMetaData targetMetadata) { var clips = new Clip[incomingClips.Length]; for (var i = 0; i < incomingClips.Length; i++) { clips[i] = new Clip(incomingClips[i]); } return(command.Id switch { TokenType.Arpeggiate => Arpeggiate.Apply(command, clips), TokenType.Concat => Concat.Apply(clips), TokenType.Crop => Crop.Apply(command, clips), TokenType.Filter => Filter.Apply(command, clips), TokenType.Invert => Invert.Apply(command, clips), TokenType.Interleave => Interleave.Apply(command, targetMetadata, clips, InterleaveMode.NotSpecified), TokenType.InterleaveEvent => Interleave.Apply(command, targetMetadata, clips, InterleaveMode.Event), TokenType.Legato => Legato.Apply(clips), TokenType.Loop => Loop.Apply(command, clips), TokenType.Mask => Mask.Apply(command, clips), TokenType.Monophonize => Monophonize.Apply(clips), TokenType.Padding => Padding.Apply(command, clips), TokenType.Quantize => Quantize.Apply(command, clips), TokenType.Ratchet => Ratchet.Apply(command, clips), TokenType.Relength => Relength.Apply(command, clips), TokenType.Remap => Remap.Apply(command, clips), TokenType.Resize => Resize.Apply(command, clips), TokenType.Scale => Scale.Apply(command, clips), TokenType.Scan => Scan.Apply(command, clips), TokenType.SetLength => SetLength.Apply(command, clips), TokenType.SetPitch => SetPitch.Apply(command, clips), TokenType.SetRhythm => SetRhythm.Apply(command, clips), TokenType.Shuffle => Shuffle.Apply(command, clips), TokenType.Skip => Skip.Apply(command, clips), TokenType.Slice => Slice.Apply(command, clips), TokenType.Take => Take.Apply(command, clips), TokenType.Transpose => Transpose.Apply(command, clips), TokenType.VelocityScale => VelocityScale.Apply(command, clips), _ => new ProcessResultArray <Clip>($"Unsupported command {command.Id}") });
public static ProcessResult <ChainedCommand> ParseFormulaToChainedCommand(string formula, List <Clip> clips, ClipMetaData metadata) { var valid = new char[] { '[', ']' }.All(c => formula.IndexOf(c) >= 0); if (!valid) { return(new ProcessResult <ChainedCommand>($"Invalid formula: {formula}")); } var lexer = new Lexer(formula, clips); var(success, tokens, errorMessage) = lexer.GetTokens(); if (!success) { return(new ProcessResult <ChainedCommand>(errorMessage)); } TreeToken syntaxTree; (success, syntaxTree, errorMessage) = CreateSyntaxTree(tokens); if (!success) { return(new ProcessResult <ChainedCommand>(errorMessage)); } // remaining steps: // convert any nested statements to inline clips - might involve some refactoring where parsing to commands and applying these can be done selectively and not as part of the fixed pipeline we have now Token[] commandTokens; (success, commandTokens, errorMessage) = ResolveAndFlattenSyntaxTree(syntaxTree); if (!success) { return(new ProcessResult <ChainedCommand>(errorMessage)); } var sourceClips = commandTokens.TakeWhile(x => x.Type == TokenType.InlineClip).Select(x => x.Clip).ToArray(); var tokensToProcess = commandTokens.Skip(sourceClips.Length).ToArray(); var commandTokensLists = ExtractCommandTokensLists(tokensToProcess); var commands = commandTokensLists.Select(ParseTokensToCommand).ToList(); var chainedCommand = new ChainedCommand(commands, sourceClips, metadata); return(new ProcessResult <ChainedCommand>(chainedCommand)); }
public static ProcessResultArray <Clip> ProcessCommand(Command command, Clip[] incomingClips, ClipMetaData targetMetadata) { var clips = new Clip[incomingClips.Length]; for (var i = 0; i < incomingClips.Length; i++) { clips[i] = new Clip(incomingClips[i]); } return(command.Id switch { TokenType.Arpeggiate => Arpeggiate.Apply(command, clips), TokenType.Concat => Concat.Apply(clips), TokenType.Crop => Crop.Apply(command, clips), TokenType.Filter => Filter.Apply(command, clips), TokenType.Interleave => Interleave.Apply(command, targetMetadata, clips), TokenType.Legato => Legato.Apply(clips), TokenType.Mask => Mask.Apply(command, clips), TokenType.Monophonize => Monophonize.Apply(clips), TokenType.Padding => Padding.Apply(command, clips), TokenType.Quantize => Quantize.Apply(command, clips), TokenType.Ratchet => Ratchet.Apply(command, clips), TokenType.Relength => Relength.Apply(command, clips), TokenType.Remap => Remap.Apply(command, clips), TokenType.Resize => Resize.Apply(command, clips), TokenType.Scale => Scale.Apply(command, clips), TokenType.Scan => Scan.Apply(command, clips), TokenType.SetLength => SetLength.Apply(command, clips), TokenType.SetPitch => SetPitch.Apply(command, clips), TokenType.SetRhythm => SetRhythm.Apply(command, clips), TokenType.Shuffle => Shuffle.Apply(command, clips), TokenType.Skip => Skip.Apply(command, clips), TokenType.Slice => Slice.Apply(command, clips), TokenType.Take => Take.Apply(command, clips), TokenType.Transpose => Transpose.Apply(command, clips), TokenType.VelocityScale => VelocityScale.Apply(command, clips), TokenType.InterleaveEvent => ((Func <ProcessResultArray <Clip> >)(() => { var(success, msg) = OptionParser.TryParseOptions(command, out InterleaveOptions options); if (!success) { return new ProcessResultArray <Clip>(msg); } options.Mode = InterleaveMode.Event; return Interleave.Apply(options, targetMetadata, clips); }))(), _ => new ProcessResultArray <Clip>($"Unsupported command {command.Id}") });
public static ProcessResult <ChainedCommand> ParseFormulaToChainedCommand(string formula, List <Clip> clips, ClipMetaData metadata) { var valid = new char[] { '[', ']' }.All(c => formula.IndexOf(c) >= 0); if (!valid) { return(new ProcessResult <ChainedCommand>($"Invalid formula: {formula}")); } var lexer = new Lexer(formula, clips); var(success, tokens, errorMessage) = lexer.GetTokens(); if (!success) { return(new ProcessResult <ChainedCommand>(errorMessage)); } TreeToken syntaxTree; (success, syntaxTree, errorMessage) = CreateSyntaxTree(tokens); if (!success) { return(new ProcessResult <ChainedCommand>(errorMessage)); } Token[] commandTokens; (success, commandTokens, errorMessage) = ResolveAndFlattenSyntaxTree(syntaxTree); if (!success) { return(new ProcessResult <ChainedCommand>(errorMessage)); } var sourceClips = commandTokens.TakeWhile(x => x.Type == TokenType.InlineClip).Select(x => x.Clip).ToArray(); var tokensToProcess = commandTokens.Skip(sourceClips.Length).ToArray(); var commandTokensLists = ExtractCommandTokensLists(tokensToProcess); var commands = commandTokensLists.Select(ParseTokensToCommand).ToList(); var chainedCommand = new ChainedCommand(commands, sourceClips, metadata); return(new ProcessResult <ChainedCommand>(chainedCommand)); }
public ChainedCommand() { Commands = new List <Command>(); SourceClips = new Clip[0]; TargetMetaData = new ClipMetaData(); }
public ChainedCommand(List <Command> commands, Clip[] sourceClips, ClipMetaData targetMetadata) { Commands = commands; SourceClips = sourceClips; TargetMetaData = targetMetadata; }
public static ProcessResultArray <Clip> ProcessCommand(Command command, Clip[] incomingClips, ClipMetaData targetMetadata) { var clips = new Clip[incomingClips.Length]; for (var i = 0; i < incomingClips.Length; i++) { clips[i] = new Clip(incomingClips[i]); } ProcessResultArray <Clip> resultContainer; switch (command.Id) { case TokenType.Arpeggiate: resultContainer = Arpeggiate.Apply(command, clips); break; case TokenType.Concat: resultContainer = Concat.Apply(clips); break; case TokenType.Crop: resultContainer = Crop.Apply(command, clips); break; case TokenType.Filter: resultContainer = Filter.Apply(command, clips); break; case TokenType.Interleave: resultContainer = Interleave.Apply(command, targetMetadata, clips); break; case TokenType.InterleaveEvent: var(success, msg) = OptionParser.TryParseOptions(command, out InterleaveOptions options); if (!success) { return(new ProcessResultArray <Clip>(msg)); } options.Mode = InterleaveMode.Event; resultContainer = Interleave.Apply(options, targetMetadata, clips); break; case TokenType.Legato: resultContainer = Legato.Apply(clips); break; case TokenType.Mask: resultContainer = Mask.Apply(command, clips); break; case TokenType.Monophonize: resultContainer = Monophonize.Apply(clips); break; case TokenType.Quantize: resultContainer = Quantize.Apply(command, clips); break; case TokenType.Ratchet: resultContainer = Ratchet.Apply(command, clips); break; case TokenType.Relength: resultContainer = Relength.Apply(command, clips); break; case TokenType.Resize: resultContainer = Resize.Apply(command, clips); break; case TokenType.Scale: resultContainer = Scale.Apply(command, clips); break; case TokenType.Scan: resultContainer = Scan.Apply(command, clips); break; case TokenType.SetLength: resultContainer = SetLength.Apply(command, clips); break; case TokenType.SetRhythm: resultContainer = SetRhythm.Apply(command, clips); break; case TokenType.Shuffle: resultContainer = Shuffle.Apply(command, clips); break; case TokenType.Skip: resultContainer = Skip.Apply(command, clips); break; case TokenType.Slice: resultContainer = Slice.Apply(command, clips); break; case TokenType.Take: resultContainer = Take.Apply(command, clips); break; case TokenType.Transpose: resultContainer = Transpose.Apply(command, clips); break; default: return(new ProcessResultArray <Clip>($"Unsupported command {command.Id}")); } return(resultContainer); }
public static ProcessResultArray <Clip> Apply(InterleaveOptions options, ClipMetaData metadata, params Clip[] clips) { if (clips.Length < 2) { clips = new[] { clips[0], clips[0] }; } decimal position = 0; int repeatsIndex = 0; Clip resultClip = new Clip(4, true); switch (options.Mode) { case Event: if (options.ChunkChords) { foreach (var clip in clips) { clip.GroupSimultaneousNotes(); } } var noteCounters = clips.Select(c => new IntCounter(c.Notes.Count)).ToArray(); position = clips[0].Notes[0].Start; while (noteCounters.Any(nc => !nc.Overflow)) { for (var clipIndex = 0; clipIndex < clips.Length; clipIndex++) { var clip = clips[clipIndex]; var currentNoteCounter = noteCounters[clipIndex]; for (var repeats = 0; repeats < options.Repeats[repeatsIndex % options.Repeats.Length]; repeats++) { var note = clip.Notes[currentNoteCounter.Value]; if (!options.Solo || clip.ClipReference.Track == metadata.TrackNumber) { var newNote = new NoteEvent(note); newNote.Start = position; resultClip.Notes.Add(newNote); } position += clip.DurationUntilNextNote(currentNoteCounter.Value); } if (options.Skip) { foreach (var noteCounter in noteCounters) { noteCounter.Inc(); } } else { currentNoteCounter.Inc(); } repeatsIndex++; } } if (options.ChunkChords) { resultClip.Flatten(); } break; case Time: var srcPositions = clips.Select(c => new DecimalCounter(c.Length)).ToArray(); int timeRangeIndex = 0; while (srcPositions.Any(c => !c.Overflow)) { for (var clipIndex = 0; clipIndex < clips.Length; clipIndex++) { var clip = clips[clipIndex]; var currentTimeRange = options.Ranges[timeRangeIndex]; for (var repeats = 0; repeats < options.Repeats[repeatsIndex % options.Repeats.Length]; repeats++) { if (!options.Solo || clip.ClipReference.Track == metadata.TrackNumber) { resultClip.Notes.AddRange( ClipUtilities.GetSplitNotesInRangeAtPosition( srcPositions[clipIndex].Value, srcPositions[clipIndex].Value + currentTimeRange, clips[clipIndex].Notes, position ) ); } position += currentTimeRange; } if (options.Skip) { foreach (var srcPosition in srcPositions) { srcPosition.Inc(currentTimeRange); } } else { srcPositions[clipIndex].Inc(currentTimeRange); } repeatsIndex++; timeRangeIndex = (timeRangeIndex + 1) % options.Ranges.Length; // this means that you cannot use the Counts parameter to have varying time ranges for each repeat } } break; } resultClip.Length = position; return(new ProcessResultArray <Clip>(new[] { resultClip })); }