<commit_before>use Music::Helpers;

multi MAIN(:$mode = 'major', Int :$root = 48, Int :$channel = 3) {
    my $mode-obj = Mode.new(:$mode, :root(NoteName($root % 12)));

    my $pm = Audio::PortMIDI.new;
    my $s  = $pm.open-output(3, 32);
    my $in = $pm.open-input($pm.default-input-device.device-id, 32);

    sub flip-flop { $ .= not }

    sub nth(Int $in) { (++$) % $in }

    my $code = supply {
        whenever supply { emit $in.poll while True } {
            emit $in.read(1);
        }
    }

    my @intervals = Interval.pick(3);

    react {
        my $next-chord;
        my $chord = $mode-obj.chords.pick;
        my $melnote = $chord.notes.pick + 12;
        my $third = $mode-obj.notes.grep({ $_.is-interval($melnote, one(M3, m3)) && $_.octave == $melnote.octave })[0];
        my $sw = 0;
        whenever $code -> $ev {
            my Audio::PortMIDI::Event @outevs;
            if $ev {
                given $ev[0].data-two {
                    my $redo = False;
                    when * +& 1 {
                        if $sw++ %% 4 {
                            @intervals = Interval.pick(6);
                            say "switching chords";
                        }
                        proceed if rand < .1;
                        $next-chord = $mode-obj.next-chord($chord, :@intervals).invert((-3, -2, -1, 0, 1, 2, 3).pick);
                        $next-chord .= invert(-1) while any($next-chord.notes>>.octave) > 4;
                        $next-chord .= invert( 1) while any($next-chord.notes>>.octave) < 3;
                        say $next-chord.Str;
                        # proceed if rand < .2;
                        for $chord.OffEvents {
                            @outevs.push: $_
                        }
                        $chord = $next-chord.invert( (-1, 0, 1).pick );
                        for $chord.OnEvents {
                            @outevs.push: $_
                        }
                        proceed;
                    }
                    when 1 < * {
                        if rand < .4 || $redo {
                            $redo = False;
                            @outevs.push: $melnote.OffEvent;
                            $melnote = $chord.notes.pick + (12, 24).pick;
                            if rand < .3 {
                                $melnote = $mode-obj.notes.grep({ $_.is-interval($melnote, any(@intervals.pick(3)) ) }).pick;
                                $redo = True;
                            }
                            @outevs.push: $melnote.?OnEvent // Empty;
                        } 
                        elsif rand < .2 {
                            @outevs.push: $third.OffEvent;
                            $third = $mode-obj.notes.grep({ $_.is-interval($melnote, one(M3, m3)) }).pick;
                            @outevs.push: $melnote.?OnEvent // Empty;
                            @outevs.push: $third.?OnEvent // Empty;
                            $redo = True;
                        }
                        proceed;
                    }
                }
                $s.write(@outevs);
                @outevs = [];
            }
        }
    }
}
<commit_msg>Remove channel argument, no one uses it anyway.<commit_after>use Music::Helpers;

multi MAIN(:$mode = 'major', Int :$root = 48) {
    my $mode-obj = Mode.new(:$mode, :root(NoteName($root % 12)));

    my $pm = Audio::PortMIDI.new;
    my $s  = $pm.open-output(3, 32);
    my $in = $pm.open-input($pm.default-input-device.device-id, 32);

    sub flip-flop { $ .= not }

    sub nth(Int $in) { (++$) % $in }

    my $code = supply {
        whenever supply { emit $in.poll while True } {
            emit $in.read(1);
        }
    }

    my @intervals = Interval.pick(5);

    react {
        my $next-chord;
        my $chord = $mode-obj.chords.pick;
        my $melnote = $chord.notes.pick + 12;
        my $third = $mode-obj.notes.grep({ $_.is-interval($melnote, one(M3, m3)) && $_.octave == $melnote.octave })[0];
        my $sw = 0;
        whenever $code -> $ev {
            my Audio::PortMIDI::Event @outevs;
            if $ev {
                given $ev[0].data-two {
                    my $redo = False;
                    when * +& 1 {
                        if $sw++ %% 4 {
                            @intervals = Interval.pick(6);
                        }
                        proceed if rand < .1;
                        $next-chord = $mode-obj.next-chord($chord, :@intervals).invert((-3, -2, -1, 0, 1, 2, 3).pick);
                        $next-chord .= invert(-1) while any($next-chord.notes>>.octave) > 4;
                        $next-chord .= invert( 1) while any($next-chord.notes>>.octave) < 3;
                        if $mode-obj.root-note.is-interval($next-chord.root, P5) {
                            say $mode-obj.root-note.is-interval($next-chord.root, P5);
                            say "dom7 and TT-subst for $next-chord";
                            say $mode-obj.root-note.Str;
                            $next-chord .= dom7;
                            $next-chord .= TT-subst if rand < .3;
                            say $next-chord.Str;
                        }
                        say $next-chord.Str;
                        # proceed if rand < .2;
                        for $chord.OffEvents {
                            @outevs.push: $_
                        }
                        $chord = $next-chord.invert( (-1, 0, 1).pick );
                        for $chord.OnEvents {
                            @outevs.push: $_
                        }
                        proceed;
                    }
                    when 1 < * {
                        if rand < .4 || $redo {
                            $redo = False;
                            @outevs.push: $melnote.OffEvent;
                            $melnote = $chord.notes.pick + (12, 24).pick;
                            if rand < .3 {
                                $melnote = $mode-obj.notes.grep({ $_.is-interval($melnote, any(@intervals.pick(3)) ) }).pick;
                                $redo = True;
                            }
                            @outevs.push: $melnote.?OnEvent // Empty;
                        } 
                        elsif rand < .2 {
                            @outevs.push: $third.OffEvent;
                            $third = $mode-obj.notes.grep({ $_.is-interval($melnote, one(M3, m3)) }).pick;
                            @outevs.push: $melnote.?OnEvent // Empty;
                            @outevs.push: $third.?OnEvent // Empty;
                            $redo = True;
                        }
                        proceed;
                    }
                }
                $s.write(@outevs);
                @outevs = [];
            }
        }
    }
}

{'fraction_non_alphanumeric': 0.13843909555069292, 'fraction_numerical': 0.01487964989059081, 'mean_word_length': 0.9258426966292135, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5125466', 'n_tokens_mistral': 2121, 'n_tokens_neox': 1963, 'n_words': 392}