Esempio n. 1
0
        public void ExportSong()
        {
            // Get the active song data
            var songData = musicChip.trackerDataCollection[patterns[currentPattern]];

            var totalNotesRendered = 0;
            int tracknum;
            int notenum;
            int gotANote;

            var tcount = songData.tracks.Length;
            var ncount = songData.tracks[0].notes.Length;

            var totalNotesInSong = ncount;                                       // total musical notes in song loops x notes

            note_tick_s     = 15.0f / songData.speedInBPM;                       // (15.0f/120.0f) = 120BPM sixteenth notes
            note_tick_s_odd = note_tick_s * swing_rhythm_factor;                 // small beat

            var notedatalength = (int)(preRenderBitrate * 2f * note_tick_s_odd); // one note worth of stereo audio (x2)

            // TODO this is off. It is happening to fast and not matching up to the correct speed of the song.
            var beatlength = preRenderBitrate * note_tick_s_odd;    // one note worth of time

            var songdatalength = notedatalength * totalNotesInSong; // stereo cd quality x song length

            var notebuffer = new float[notedatalength];

            if (trackresult == null)
            {
                // all the tracks we need - an array of audioclips that will be merged into result
                trackresult = new RawAudioData[tcount];

                for (var i = 0; i < tcount; i++)
                {
                    trackresult[i] = new RawAudioData(0, 1,
                                                      preRenderBitrate);
                }
            }

            var instrument = new SfxrSynth[songData.totalTracks];

            var newStartPos = trackresult[0].samples / 2;
            var newLength   = trackresult[0].samples + songdatalength;


            for (tracknum = 0; tracknum < tcount; tracknum++)
            {
                if (instrument[tracknum] == null)
                {
                    instrument[tracknum] = new SfxrSynth();
                }


                var songdataCurrentPos = newStartPos;
                trackresult[tracknum].Resize(newLength);

                // set the params to current track's instrument string
                instrument[tracknum].parameters
                .SetSettingsString(soundChip.ReadSound(songData.tracks[tracknum].sfxID).param);

                // Loop through all of the notes in the track
                for (notenum = 0; notenum < ncount; notenum++)
                {
                    // what note is it?
                    gotANote = songData.tracks[tracknum].notes[notenum];

                    // generate one note worth of audio data
                    if (gotANote > 0 && instrument[tracknum] != null)
                    {
                        //instrument[tracknum].Reset(true); // seems to do nothing

                        // doing this for every note played is insane:
                        // try a fresh new instrument (RAM and GC spammy)
                        instrument[tracknum] = new SfxrSynth(); // shouldn't be required, but for some reason it is
                        // set the params to current track's instrument string
                        instrument[tracknum].parameters
                        .SetSettingsString(soundChip.ReadSound(songData.tracks[tracknum].sfxID).param);


                        // pitch shift the sound to the correct musical note frequency
                        instrument[tracknum].parameters.startFrequency = noteStartFrequency[gotANote];


                        // maybe this will help
                        // instrument[tracknum].GenerateAudioFilterData(float[] __data, int __channels)

                        // or perhaps this - nope: outputs silence... hmm
                        //bool gotAllData = instrument[tracknum].SynthWave(notebuffer, 0, (uint)notedatalength);// (uint)notebuffer.Length);

                        // unlikely but helpful - used by GenerateAudioFilterData
                        // WriteSamples(float[] __originSamples, int __originPos, float[] __targetSamples, int __targetChannels) {
                        // Writes raw samples to Unity's format and return number of samples actually written

                        // does play need to be called for it to be generated properly?
                        instrument[tracknum].CacheSound(); // generate cachedWave data

                        // grab the sample data - this data is not in the same fmt as unity's internal?
                        // sounds pitch-shifted and faster - a different bitrate?
                        // WORKS GREAT IF WE RUN CACHESOUND() FIRST
                        // TODO need to figure out why we can't access the cachedWave
                        notebuffer = instrument[tracknum].data; // the wave data for the current note

                        // this SHOULD be the solution. but outputs all 0's
                        //bool gotAllData = instrument[tracknum].GenerateAudioFilterData(notebuffer, 2);


                        // move sound data into audioclip buffer
                        if (notebuffer != null && notebuffer.Length > 0)
                        {
                            trackresult[tracknum].SetData(notebuffer, songdataCurrentPos);
                        }
                        //                            else
                        //                                Debug.LogWarning("Notebuffer was blank. Ignoring.");

                        totalNotesRendered++;
                    }

                    // TODO converted this to an int, may break?
                    songdataCurrentPos += (int)beatlength;  //notedatalength; this is x2 due to stereo

                    //yield return null; // if here, min one frame PER note PER track PER loop: too slow
                } // for all notes
            }     // for all tracks


            currentPattern++;
            currentStep++;
        }