Esempio n. 1
0
    /*************************************************************************//**
    * @}
    * @defgroup SongStatFunc Static Functions
    * @ingroup DocSong
    * Functions related to @link Song Songs@endlink that can be used without having to have an actual instance of a Song.
    * @{
    *****************************************************************************/

    /**
     * @brief Gets the number of waveform samples required to accurately represent the @link Music::NOTE_LENGTH_BASE length of a note@endlink for a given @link DefBPM BPM@endlink and @link Music::TimeSignature time signature@endlink.
     * @param[in] aBPM The @link DefBPM BPM@endlink that should be accounted for.
     * @param[in] aSampleRate The sample rate of the note. Might need to remove since most likely everything's going to have a 44\.1KHz sample rate.
     * @param[in] aNoteLength The @link Music::NOTE_LENGTH_BASE note length@endlink that's being converted into a number of waveform samples.
     * @param[in] aTimeSignature The @link Music::TimeSignature time signature@endlink that should be accounted for.
     * @return The number of waveform samples that represents the given @link Music::NOTE_LENGTH_BASE note length@endlink at the given @link DefBPM BPM@endlink and @link Music::TimeSignature time signature@endlink.
     *
     */
    public static int GetNoteLengthInSamples(int aBPM, int aSampleRate, Music.NoteLength aNoteLength, Music.TimeSignature aTimeSignature)
    {
        // Initialize variables for calculating the note length.
        float beatsPerSecond = (float)aBPM / 60f;

        // Since the audio data is split into two channels with even indices for the data
        // in the left channel and odd indices for the data in the right channel, the
        // actual conversion for number of samples per second is 2 * sample rate.
        float numSamplesPerBeat = 2f * (1f / beatsPerSecond) * (float)aSampleRate;

        // Calculate the length for various time signatures by relating the base beat to
        // a quarter note.
        float numQuarterNotesPerBeat = 1f;

        // Right now, only provide support for base beats of 4 and 8.
        switch (aTimeSignature.BaseBeat)
        {
        case Music.NOTE_LENGTH_BASE.E:
            numQuarterNotesPerBeat /= 2f;
            break;

        default:
            break;
        }

        // Calculate the note length in samples.
        return((int)(numSamplesPerBeat * (Music.GetNoteLengthRelativeToQuarterNote(aNoteLength) * numQuarterNotesPerBeat)));
    }
 /**
  * @brief Sets the @link Music::NoteLength note length@endlink for the panel.
  * @param[in] aNoteLength The @link Music::NoteLength note length@endlink for the panel.
  */
 public void SetSelected(Music.NoteLength aNoteLength)
 {
     mNoteLength         = aNoteLength;
     mDotToggle.isOn     = aNoteLength.Dot;
     mTripletToggle.isOn = aNoteLength.Triplet;
     mBaseLengthToggles[(int)aNoteLength.BaseLength].isOn = true;
     UpdateGraphics();
 }
Esempio n. 3
0
    /**
     * @brief Handles @link Music::PITCH pitches@endlink being added.
     * @param[in] aPitches The selected @link Music::PITCH pitches@endlink.
     * @param[in] aLength The selected @link Music::NoteLength length@endlink.
     * @param[in] aVelocity The selected @link DefVel velocity@endlink.
     */
    private void OnPitchesAdded(Music.PITCH[] aPitches, Music.NoteLength aLength, int aVelocity)
    {
        // Add the pitches to the display container and the melody note.
        foreach (Music.PITCH pitch in aPitches)
        {
            // Create a pitch/drum display panel and get its script.
            GameObject clone = Instantiate(Resources.Load <GameObject>(PDDP_PREFAB_PATH));
            SC_PitchDrumDisplayPanel newPanel = clone.AddComponent <SC_PitchDrumDisplayPanel>();

            // Initialize the panel's values and add it to the list.
            newPanel.InitializeAsPitchDisplay(pitch, aLength, aVelocity);
            newPanel.SetParentContainer(this);
            mPitches.Add(newPanel);

            // Put the new panel in the melody display.
            clone.transform.SetParent(mMelodyDisplay, false);
        }
        UpdateDoneButton();
    }
    /**
     * @brief Sets up the SC_PitchDrumDisplayPanel as a display panel for @link Music::PITCH pitches@endlink.
     * @param[in] aPitch The @link Music::PITCH pitch@endlink that is being represented.
     * @param[in] aLength @copydoc SC_PitchDrumDisplayPanel::mLength
     * @param[in] aNoteVelocity @copydoc SC_PitchDrumDisplayPanel::mNoteVelocity
     */
    public void InitializeAsPitchDisplay(Music.PITCH aPitch, Music.NoteLength aLength, int aNoteVelocity)
    {
        // Set that the panel is not representing drums.
        mIsDrum = false;

        // Set the pitch.
        mPitch = aPitch;

        // Set the pitch display text.
        mPitchDisplay.text = "Pitch:\n" + Music.NoteToString(aPitch);

        // Set the length.
        mLength = aLength;

        // See if we need to set the length image..
        if (aLength.BaseLength == Music.NOTE_LENGTH_BASE.NONE)
        {
            mLengthPanel.SetActive(false);
            mDotModifierPanel.SetActive(false);
            mTripletModifierPanel.SetActive(false);
        }
        else
        {
            // Set the length image.
            mLengthPanel.transform.GetChild(1).GetComponent <Image>().sprite = Music.GetImageForNoteLength(aLength.BaseLength);

            // Set the modifier images.
            if (!aLength.Dot)
            {
                mDotModifierPanel.SetActive(false);
            }
            if (!aLength.Triplet)
            {
                mTripletModifierPanel.SetActive(false);
            }
        }


        // Set the velocity.
        mNoteVelocity = aNoteVelocity;
        mNoteVelocityHandler.SetValue(aNoteVelocity);
    }
Esempio n. 5
0
    /**
     * @brief Handles the Add Note button being clicked by loading a @link DocSC_NDia Note Dialog@endlink.
     */
    public void OnNewNoteButtonClicked()
    {
        // Load the dialog.
        GameObject dialogObj = Instantiate(Resources.Load <GameObject>(NOTE_DIALOG_PATH));

        dialogObj.transform.SetParent(transform, true);
        SC_NoteDialog dialog = dialogObj.transform.GetChild(0).GetComponent <SC_NoteDialog>();

        // Get the initial offset for the note dialog.
        Music.NoteLength dialogOffset = new Music.NoteLength(Music.NOTE_LENGTH_BASE.NONE);
        if (mSong.GetNumNotes() > 0)
        {
            // Get the last note to find the initial offset.
            int lastNoteIndex           = mSong.GetNumNotes() - 1;
            Music.CombinedNote lastNote = mSong.GetNote(lastNoteIndex);

            // If there are pitches in the last note, then set the dialog's offset to
            // be the shortest length of all of the pitches in the last note.
            if (lastNote.NumPitches > 0)
            {
                Music.NoteLength shortestLength = lastNote.MusicalNote.Lengths[0];
                for (int i = 1; i < lastNote.NumPitches; i++)
                {
                    if (lastNote.MusicalNote.Lengths[i] < shortestLength)
                    {
                        shortestLength = lastNote.MusicalNote.Lengths[i];
                    }
                }
                dialogOffset = shortestLength;
            }
            // If there are not pitches in the last note, then set it to
            // the last note's offset.
            else
            {
                dialogOffset = lastNote.OffsetFromPrevNote;
            }
        }

        dialog.SetDefaultOffset(dialogOffset);
        dialog.NoteDialogFinished.AddListener(OnCreateNote);
    }
Esempio n. 6
0
    /**
     * @brief Updates the todoclength panel when a todocnote is loaded into the display panel.
     * @param[in] aNote The todocnote to display
     */
    private void UpdateLengthPanel()
    {
        // Set the length panel.
        mLengthPanel.gameObject.SetActive(true);

        if (mNote.NumPitches > 0)
        {
            // See whether or not there are multiple lengths.
            int              index       = 1;
            bool             multiple    = false;
            Music.NoteLength firstLength = mNote.MusicalNote.Lengths[0];
            while (index < mNote.NumPitches && !multiple)
            {
                if (mNote.MusicalNote.Lengths[index] != firstLength)
                {
                    multiple = true;
                }
                index++;
            }

            // Display that there are multiple lengths if needed.
            if (multiple)
            {
                mMultipleLengthText.gameObject.SetActive(true);
                mNoLengthText.gameObject.SetActive(false);
                mBaseLengthPanel.gameObject.SetActive(false);
                mDotLengthPanel.gameObject.SetActive(false);
                mTripletLengthPanel.gameObject.SetActive(false);
            }
            // Display the common length if all pitches have the same length.
            else
            {
                mMultipleLengthText.gameObject.SetActive(false);

                // If the length is none, then display it.
                if (firstLength.BaseLength == Music.NOTE_LENGTH_BASE.NONE)
                {
                    mNoLengthText.gameObject.SetActive(true);
                }
                // Display the length as an image if there is a length.
                else
                {
                    mNoLengthText.gameObject.SetActive(false);
                    mBaseLengthPanel.gameObject.SetActive(true);
                    mBaseLengthPanel.GetChild(0).GetComponent <Image>().sprite = Music.GetImageForNoteLength(firstLength.BaseLength);

                    // Display the length modifiers if needed.
                    mDotLengthPanel.gameObject.SetActive(firstLength.Dot);
                    mTripletLengthPanel.gameObject.SetActive(firstLength.Triplet);
                }
            }
        }
        // Handle when there are no pitches
        else
        {
            mNoLengthText.gameObject.SetActive(true);

            mBaseLengthPanel.gameObject.SetActive(false);
            mDotLengthPanel.gameObject.SetActive(false);
            mTripletLengthPanel.gameObject.SetActive(false);
            mMultipleLengthText.gameObject.SetActive(false);
        }
    }
Esempio n. 7
0
    /**
     * @brief Handles the done button being clicked.
     */
    private void OnDoneButtonClicked()
    {
        // Set up the pitches.
        int numPitches = mPitches.Count;

        Music.PITCH[]      pitches         = null;
        int[]              pitchVelocities = null;
        Music.NoteLength[] lengths         = null;

        // If there are pitches, then get them from the panels.
        if (numPitches != 0)
        {
            // Get all of the pitches, velocities, and lengths.
            pitches         = new Music.PITCH[numPitches];
            pitchVelocities = new int[numPitches];
            lengths         = new Music.NoteLength[numPitches];
            int index = 0;
            foreach (SC_PitchDrumDisplayPanel pitch in mPitches)
            {
                pitches[index]         = pitch.GetPitch();
                pitchVelocities[index] = pitch.GetNoteVelocity();
                lengths[index]         = pitch.GetLengthOfPitch();
                index++;
            }
        }

        // Create the melody note.
        Music.MelodyNote melody = new Music.MelodyNote(pitchVelocities, lengths, pitches);

        // Set up the drums.
        int numDrums = mDrums.Count;

        Music.DRUM[] drums          = null;
        int[]        drumVelocities = null;

        // If there are drums, then get them from the panels.
        if (numDrums != 0)
        {
            // Get all of the drums and their velocities.
            drums          = new Music.DRUM[numDrums];
            drumVelocities = new int[numDrums];
            int index = 0;
            foreach (SC_PitchDrumDisplayPanel drum in mDrums)
            {
                drums[index]          = drum.GetDrum();
                drumVelocities[index] = drum.GetNoteVelocity();
                index++;
            }
        }

        // Create the percussion note.
        Music.PercussionNote percussion = new Music.PercussionNote(drumVelocities, drums);

        // Get the offset of the note.
        Music.NoteLength offset = mOffsetPanel.GetSelected();

        // Create the note.
        Music.CombinedNote note = new Music.CombinedNote(melody, percussion, offset);

        // Invoke the event which signals the dialog being finished.
        NoteDialogFinished.Invoke(note);

        // Self-destruct.
        DestroyImmediate(transform.parent.gameObject, false);
    }
Esempio n. 8
0
 /**
  * @brief Sets the default todocoffset for the dialog. Usually based on the previous todocnote in the Song.
  * @param[in] aOffset The default todocoffset.
  */
 public void SetDefaultOffset(Music.NoteLength aOffset)
 {
     mOffsetPanel.SetSelected(aOffset);
 }
    /*************************************************************************//**
    * @}
    * @defgroup SC_APDHandlers Event Handlers
    * @ingroup DocSC_APD
    * These are functions called by the SC_AddPitchDialog in order to handle events.
    * @{
    *****************************************************************************/

    /**
     * @brief Sets the default length
     * @param[in] aLength The default length
     */
    public void SetDefaultLength(Music.NoteLength aLength)
    {
        mLengthSelector.SetSelected(aLength);
    }
Esempio n. 10
0
    /*************************************************************************//**
    * @}
    * @defgroup SongPrivFunc Private Functions
    * @ingroup DocSong
    * Functions used internally by the Song.
    * @{
    *****************************************************************************/

    /**
     * @brief Loads a @link DocSongFileFormat Song file@endlink and uses it to set the values for this Song.
     * @param[in] aSongFilePath The path to the Song file.
     * @see @link DocSongFileFormat Song File Format@endlink
     */
    private void LoadSongFromFile(string aSongFilePath)
    {
        // Create some variables for parsing the file.
        Music.PITCH[]             curNotePitches = null;
        Music.DRUM[]              curNoteDrums   = null;
        Music.NoteLength[]        curNoteLengths = null;
        List <Music.CombinedNote> notesInFile    = new List <Music.CombinedNote>();
        int splitLineIndex = 0;

        int[] curNoteMelodyVelocities = null;
        int[] curNoteDrumVelocities   = null;

        // Open the file stream.
        StreamReader parser = new StreamReader(aSongFilePath);

        // Get the name of the Song
        string curLine = parser.ReadLine();

        mName = curLine;

        // Get the Song type.
        curLine = parser.ReadLine();
        string[] splitLine = curLine.Split(';');
        mType = (SongType)int.Parse(splitLine[0]);

        // Get the default BPM
        mBPM = int.Parse(splitLine[1]);

        // Get the time signature
        mTimeSignature.BeatsPerMeasure = int.Parse(splitLine[2]);
        mTimeSignature.BaseBeat        = (Music.NOTE_LENGTH_BASE) int.Parse(splitLine[3]);

        // Get the notes of the Song.
        curLine = parser.ReadLine();
        while (curLine != null)
        {
            // Get the line and reset the split line index.
            splitLine      = curLine.Split(';');
            splitLineIndex = 0;

            // Get the pitches for the note if needed.
            if (mType != SongType.DrumLoop)
            {
                curNotePitches = ParsePitches(splitLine[splitLineIndex]);
            }

            // Get the drums for the note if needed.
            if (mType != SongType.Melody)
            {
                curNoteDrums = ParseDrums(splitLine[splitLineIndex]);
            }

            // Go to the next section of the line.
            splitLineIndex++;

            // If needed, get the melody note lengths.
            if (mType != SongType.DrumLoop)
            {
                // Reset the note length array.
                curNoteLengths = null;

                // See if there are lengths for the note.
                if (splitLine[splitLineIndex] != "null")
                {
                    // Get the lengths
                    string[] lengths = splitLine[splitLineIndex].Split(',');
                    curNoteLengths = new Music.NoteLength[lengths.Length];
                    for (int i = 0; i < curNoteLengths.Length; i++)
                    {
                        // Use the constructor for the NoteLength struct that takes a string parameter.
                        curNoteLengths[i] = new Music.NoteLength(lengths[i]);
                    }
                    lengths = null;
                }

                // Go to the next section.
                splitLineIndex++;
            }

            // Get the offset from the previous note.
            Music.NoteLength offset = new Music.NoteLength(splitLine[splitLineIndex]);
            splitLineIndex++;

            // Get the velocities of the note.
            if (mType == SongType.CombinedMelodyAndPercussion)
            {
                // If this Song is a combined Song, then get velocities for both drums and melody.
                string[] allVelocitiesString = splitLine[splitLineIndex].Split('|');

                // Get the melody velocities if there are any for this note.
                if (allVelocitiesString[0] != "null")
                {
                    string[] melodyVelocitiesString = allVelocitiesString[0].Split(',');
                    curNoteMelodyVelocities = new int[melodyVelocitiesString.Length];
                    for (int i = 0; i < curNoteMelodyVelocities.Length; i++)
                    {
                        curNoteMelodyVelocities[i] = int.Parse(melodyVelocitiesString[i]);
                    }
                    melodyVelocitiesString = null;
                }

                // Get the drum velocities if there are any for this note.
                if (allVelocitiesString[1] != "null")
                {
                    string[] drumVelocitiesString = allVelocitiesString[1].Split(',');
                    curNoteDrumVelocities = new int[drumVelocitiesString.Length];
                    for (int i = 0; i < curNoteDrumVelocities.Length; i++)
                    {
                        curNoteDrumVelocities[i] = int.Parse(drumVelocitiesString[i]);
                    }
                    drumVelocitiesString = null;
                }
            }
            // If this Song is a melody, then get the melody velocities for the note.
            else if (mType == SongType.Melody)
            {
                string[] melodyVelocitiesString = splitLine[splitLineIndex].Split(',');
                curNoteMelodyVelocities = new int[melodyVelocitiesString.Length];
                for (int i = 0; i < curNoteMelodyVelocities.Length; i++)
                {
                    curNoteMelodyVelocities[i] = int.Parse(melodyVelocitiesString[i]);
                }
                melodyVelocitiesString = null;
            }
            // If the Song is a drum loop, then get the drum velocities for the note.
            else
            {
                string[] drumVelocitiesString = splitLine[splitLineIndex].Split(',');
                curNoteDrumVelocities = new int[drumVelocitiesString.Length];
                for (int i = 0; i < curNoteDrumVelocities.Length; i++)
                {
                    curNoteDrumVelocities[i] = int.Parse(drumVelocitiesString[i]);
                }
                drumVelocitiesString = null;
            }

            // Add the note to the temp list.
            Music.MelodyNote     melody     = new Music.MelodyNote(curNoteMelodyVelocities, curNoteLengths, curNotePitches);
            Music.PercussionNote percussion = new Music.PercussionNote(curNoteDrumVelocities, curNoteDrums);
            notesInFile.Add(new Music.CombinedNote(melody, percussion, offset));

            curNoteMelodyVelocities = null;
            curNoteDrumVelocities   = null;
            curNoteLengths          = null;

            // Get the next line
            curLine = parser.ReadLine();
        }
        parser.Close();

        // Put the notes from the file into the Song.
        foreach (Music.CombinedNote note in notesInFile)
        {
            AddNote(note);
        }

        // Clean up.
        notesInFile.Clear();
        notesInFile = null;
        Resources.UnloadUnusedAssets();
    }