<commit_before>﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SongPlayback : MonoBehaviour {
    public bool isPlaying { get { return m_IsPlaying; } }
    public int playbackRate { get { return m_PlaybackRate; } }
    public int patternLoop { get { return m_PatternLoop; } }
    public int currentPattern { get { return m_PlayingPattern; } }
    public int internalPattern { get { return m_CurrentPattern; } }
    public float songProgress { get { return ( float ) m_CurrentPattern / ( float ) data.numPatterns; } }
    public int[] chnAttn { get { return m_ChnAttenuation; } }
    public int loops { get { return m_PlayLoops; } set { m_PlayLoops = System.Math.Max ( -1, value ); } }

    public PSGWrapper psg;
    public SongData data;
    public PatternView view;
    public Instruments instruments;
    public VirtualKeyboard keyboard;
    public int playbackSpeed;
    public bool follow = true;
    public bool[] mute;

    private int m_CurrentPattern;
    private int m_PlayingPattern;
    private int m_CurrentLine;
    private int m_Counter;
    private long m_StartSample;
    private bool m_IsPlaying;
    private bool m_IsStopping;
    private float m_LastLineTick;
    private int m_MoveLine;
    private Instruments.InstrumentInstance[] m_Instruments;
    private Instruments.InstrumentInstance[] m_PrevInstruments;
    private bool m_NoiseFB;
    private bool m_NoiseChn3;
    private int m_PlaybackRate = 50;
    private int m_PatternLoop = 0;
    private int m_PlayLoops = -1;
    private int m_Loops = -1;
    private int[] m_ChnAttenuation = new int[4];
    private int m_PatternBreakTarget = -1;

    void Start()
    {
        psg.AddIrqCallback(m_PlaybackRate, OnIrqCallback);
        psg.AddIrqCallback(Instruments.InstrumentInstance.SAMPLE_RATE, OnSampleCallback);
        mute = new bool [ data.channels ];
        m_Instruments = new Instruments.InstrumentInstance [ data.channels ];
        m_PrevInstruments = new Instruments.InstrumentInstance[data.channels];
    }

    void Update()
    {
        if (!ExclusiveFocus.currentFocus && Input.GetKeyDown(KeyCode.Return))
        {
            if (m_IsPlaying)
                Stop();
            else
                Play( true );
        }

        if(follow && m_IsPlaying && Time.time - m_LastLineTick > 1f / 50f) {
            while ( m_MoveLine > 0 ) {
                m_MoveLine--;
                
                if (m_PatternBreakTarget >= 0) {
                    data.currentPattern++;
                    view.selectedLine = m_PatternBreakTarget;
                    m_PatternBreakTarget = -1;
                    
                    view.UpdatePatternData();
                    continue;
                }
                
                view.selectedLine++;
                if ( view.selectedLine == 0 ) {
                    data.currentPattern++;
                    if ( data.currentPattern >= data.numPatterns )
                        data.currentPattern = m_PatternLoop;

                    view.UpdatePatternData ( );
                }

                m_LastLineTick = Time.time;
            }
        }
    }

    public void OnSampleCallback()
    {
        if (!m_IsPlaying)
            return;

        for (int i = 0; i < data.channels; i++)
        {
            if ( m_Instruments [ i ].noteDelay > 0 )
                m_PrevInstruments [ i ].UpdatePSGSample ( psg, i );
            else
                m_Instruments [ i ].UpdatePSGSample ( psg, i );
        }
    }

    public void OnIrqCallback()
    {
        if (!m_IsPlaying)
            return;

        m_Counter++;

        if(m_Counter >= playbackSpeed)
        {
            if ( m_IsStopping ) {
                m_IsPlaying = false;
                m_IsStopping = true;
                return;
            }

            m_Counter = 0;
            int patternBreakTarget = -1;
            
            for (int i = 0; i < data.channels; i++)
            {
                if ( mute [ i ] ) {
                    m_Instruments [ i ].note = VirtualKeyboard.Note.NoteOff;
                    continue;
                }

                m_PlayingPattern = m_CurrentPattern;
                SongData.ColumnEntry col = data.GetPatternColumn(m_CurrentPattern, i);

                if ( col == null ) {
                    //m_Instruments [ i ].note = VirtualKeyboard.Note.NoteOff;
                    //psg.SetAttenuation ( i, 0 );
                    continue;
                }

                int volume = col.data [ m_CurrentLine, 2 ];
                if ( volume >= 0 ) {
                    m_Instruments [ i ].relativeVolume = volume;
                }

                if (col.data[m_CurrentLine, 0] > 0)
                {
                    VirtualKeyboard.Note note = VirtualKeyboard.GetNote ( col.data [ m_CurrentLine, 0 ] );
                    if ( note == VirtualKeyboard.Note.NoteOff ) {
                        m_Instruments [ i ].note = VirtualKeyboard.Note.NoteOff;
                        psg.SetAttenuation ( i, 0 );
                    } else if (col.data[m_CurrentLine, 1] < instruments.presets.Length) {
                        m_PrevInstruments [ i ] = m_Instruments [ i ];
                        m_Instruments [ i ] = instruments.presets [ col.data [ m_CurrentLine, 1 ] ];
                        m_Instruments [ i ].relativeVolume = volume >= 0 ? volume : 0xF;
                        m_Instruments [ i ].note = note;
                        m_Instruments [ i ].noteOffset = data.transposeTable [ m_CurrentPattern ] [ i ];
                        m_Instruments [ i ].octave = VirtualKeyboard.GetOctave ( col.data [ m_CurrentLine, 0 ] );
                    } 
                }


                int fxVal = col.data [ m_CurrentLine, 4 ];

                if ( fxVal >= 0 ) {
                    switch ( col.data [ m_CurrentLine, 3 ] ) {
                        //arpreggio
                        case 0x00:
                            if ( fxVal == 0 ) {
                                m_Instruments [ i ].arpeggio = new int [ 0 ];
                            } else {
                                int hiArp, loArp;
                                SplitByte ( fxVal, out hiArp, out loArp );
                                m_Instruments [ i ].arpeggio = new int [ 3 ] { 0, loArp, hiArp };
                                m_Instruments[i].arpLoopPoint = 3;
                            }
                            break;

                        case 0x01:
                            m_Instruments [ i ].portamentoSpeed = fxVal;<commit_msg>Muting no longer mutes global trackfx<commit_after>﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class SongPlayback : MonoBehaviour {
    public bool isPlaying { get { return m_IsPlaying; } }
    public int playbackRate { get { return m_PlaybackRate; } }
    public int patternLoop { get { return m_PatternLoop; } }
    public int currentPattern { get { return m_PlayingPattern; } }
    public int internalPattern { get { return m_CurrentPattern; } }
    public float songProgress { get { return ( float ) m_CurrentPattern / ( float ) data.numPatterns; } }
    public int[] chnAttn { get { return m_ChnAttenuation; } }
    public int loops { get { return m_PlayLoops; } set { m_PlayLoops = System.Math.Max ( -1, value ); } }

    public PSGWrapper psg;
    public SongData data;
    public PatternView view;
    public Instruments instruments;
    public VirtualKeyboard keyboard;
    public int playbackSpeed;
    public bool follow = true;
    public bool[] mute;

    private int m_CurrentPattern;
    private int m_PlayingPattern;
    private int m_CurrentLine;
    private int m_Counter;
    private long m_StartSample;
    private bool m_IsPlaying;
    private bool m_IsStopping;
    private float m_LastLineTick;
    private int m_MoveLine;
    private Instruments.InstrumentInstance[] m_Instruments;
    private Instruments.InstrumentInstance[] m_PrevInstruments;
    private bool m_NoiseFB;
    private bool m_NoiseChn3;
    private int m_PlaybackRate = 50;
    private int m_PatternLoop = 0;
    private int m_PlayLoops = -1;
    private int m_Loops = -1;
    private int[] m_ChnAttenuation = new int[4];
    private int m_PatternBreakTarget = -1;

    void Start()
    {
        psg.AddIrqCallback(m_PlaybackRate, OnIrqCallback);
        psg.AddIrqCallback(Instruments.InstrumentInstance.SAMPLE_RATE, OnSampleCallback);
        mute = new bool [ data.channels ];
        m_Instruments = new Instruments.InstrumentInstance [ data.channels ];
        m_PrevInstruments = new Instruments.InstrumentInstance[data.channels];
    }

    void Update()
    {
        if (!ExclusiveFocus.currentFocus && Input.GetKeyDown(KeyCode.Return))
        {
            if (m_IsPlaying)
                Stop();
            else
                Play( true );
        }

        if(follow && m_IsPlaying && Time.time - m_LastLineTick > 1f / 50f) {
            while ( m_MoveLine > 0 ) {
                m_MoveLine--;
                
                if (m_PatternBreakTarget >= 0) {
                    data.currentPattern++;
                    view.selectedLine = m_PatternBreakTarget;
                    m_PatternBreakTarget = -1;
                    
                    view.UpdatePatternData();
                    continue;
                }
                
                view.selectedLine++;
                if ( view.selectedLine == 0 ) {
                    data.currentPattern++;
                    if ( data.currentPattern >= data.numPatterns )
                        data.currentPattern = m_PatternLoop;

                    view.UpdatePatternData ( );
                }

                m_LastLineTick = Time.time;
            }
        }
    }

    public void OnSampleCallback()
    {
        if (!m_IsPlaying)
            return;

        for (int i = 0; i < data.channels; i++)
        {
            if ( m_Instruments [ i ].noteDelay > 0 )
                m_PrevInstruments [ i ].UpdatePSGSample ( psg, i );
            else
                m_Instruments [ i ].UpdatePSGSample ( psg, i );
        }
    }

    public void OnIrqCallback()
    {
        if (!m_IsPlaying)
            return;

        m_Counter++;

        if(m_Counter >= playbackSpeed)
        {
            if ( m_IsStopping ) {
                m_IsPlaying = false;
                m_IsStopping = true;
                return;
            }

            m_Counter = 0;
            int patternBreakTarget = -1;
            
            for (int i = 0; i < data.channels; i++)
            {

                m_PlayingPattern = m_CurrentPattern;
                SongData.ColumnEntry col = data.GetPatternColumn(m_CurrentPattern, i);

                if ( col == null ) {
                    //m_Instruments [ i ].note = VirtualKeyboard.Note.NoteOff;
                    //psg.SetAttenuation ( i, 0 );
                    continue;
                }
                if (mute[i]) {
                    m_Instruments[i].note = VirtualKeyboard.Note.NoteOff;
                } else {
                    int volume = col.data[m_CurrentLine, 2];
                    if (volume >= 0) {
                        m_Instruments[i].relativeVolume = volume;
                    }

                    if (col.data[m_CurrentLine, 0] > 0) {
                        VirtualKeyboard.Note note = VirtualKeyboard.GetNote(col.data[m_CurrentLine, 0]);
                        if (note == VirtualKeyboard.Note.NoteOff) {
                            m_Instruments[i].note = VirtualKeyboard.Note.NoteOff;
                            psg.SetAttenuation(i, 0);
                        }
                        else if (col.data[m_CurrentLine, 1] < instruments.presets.Length) {
                            m_PrevInstruments[i] = m_Instruments[i];
                            m_Instruments[i] = instruments.presets[col.data[m_CurrentLine, 1]];
                            m_Instruments[i].relativeVolume = volume >= 0 ? volume : 0xF;
                            m_Instruments[i].note = note;
                            m_Instruments[i].noteOffset = data.transposeTable[m_CurrentPattern][i];
                            m_Instruments[i].octave = VirtualKeyboard.GetOctave(col.data[m_CurrentLine, 0]);
                        }
                    }
                }


                int fxVal = col.data [ m_CurrentLine, 4 ];

                if ( fxVal >= 0 ) {
                    switch ( col.data [ m_CurrentLine, 3 ] ) {
                        //arpreggio
                        case 0x00:
                            if ( fxVal == 0 ) {
                                m_Instruments [ i ].arpeggio = new int [ 0 ];
                            } else {
                                int hiArp, loArp;
                                SplitByte ( fxVal, out hiArp, out loArp );
                                m_Instruments [ i ].arpeggio = new int [ 3 ] { 0, loArp, hiArp };
                                m_Instruments[i].arpLoopPoint = 3;
                            }
                            break;

                        case 0x01:
                            m_Instruments [ i ].portamentoSpeed = fxVal;
{'fraction_non_alphanumeric': 0.0845443536179231, 'fraction_numerical': 0.007114744171964881, 'mean_word_length': 1.3923592250588448, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7218853', 'n_tokens_mistral': 3799, 'n_tokens_neox': 3477, 'n_words': 818}