예제 #1
0
        private void Props_PropertyChanged(PropertyPage props, int propIdx, int rowIdx, int colIdx, object value)
        {
            if (song.UsesFamiTrackerTempo)
            {
                var tempo = song.FamitrackerTempo;
                var speed = song.FamitrackerSpeed;

                if (propIdx == famitrackerTempoPropIdx ||
                    propIdx == famitrackerSpeedPropIdx)
                {
                    tempo = props.GetPropertyValue <int>(famitrackerTempoPropIdx);
                    speed = props.GetPropertyValue <int>(famitrackerSpeedPropIdx);
                }

                var beatLength = props.GetPropertyValue <int>(notesPerBeatPropIdx);

                props.SetLabelText(bpmLabelPropIdx, Song.ComputeFamiTrackerBPM(song.Project.PalMode, speed, tempo, beatLength).ToString("n1"));
            }
            else
            {
                var notesPerBeat = props.GetPropertyValue <int>(notesPerBeatPropIdx);

                // Changing the number of notes in a beat will affect the list of available BPMs.
                if (propIdx == notesPerBeatPropIdx)
                {
                    tempoList    = FamiStudioTempoUtils.GetAvailableTempos(song.Project.PalMode, notesPerBeat);
                    tempoStrings = tempoList.Select(t => t.bpm.ToString("n1") + (t.groove.Length == 1 ? " *" : "")).ToArray();
                    props.UpdateDropDownListItems(famistudioBpmPropIdx, tempoStrings);
                }

                // Changing the BPM affects the grooves and note length.
                if (propIdx == famistudioBpmPropIdx ||
                    propIdx == notesPerBeatPropIdx)
                {
                    var tempoIndex    = Array.IndexOf(tempoStrings, props.GetPropertyValue <string>(famistudioBpmPropIdx));
                    var tempoInfo     = tempoList[tempoIndex];
                    var framesPerNote = Utils.Min(tempoInfo.groove);

                    props.UpdateIntegerRange(notesPerPatternPropIdx, 1, Pattern.MaxLength / framesPerNote);

                    var grooveList = FamiStudioTempoUtils.GetAvailableGrooves(tempoInfo.groove);
                    grooveStrings = grooveList.Select(g => string.Join("-", g)).ToArray();

                    props.UpdateDropDownListItems(groovePropIdx, grooveStrings);
                    props.SetLabelText(framesPerNotePropIdx, framesPerNote.ToString());
                }
            }

            UpdateWarnings();
        }
예제 #2
0
        private void WavMp3_PropertyChanged(PropertyPage props, int propIdx, int rowIdx, int colIdx, object value)
        {
            if (propIdx == 1)
            {
                props.SetPropertyEnabled(3, (string)value != "WAV");
            }
            else if (propIdx == 4)
            {
                props.SetPropertyEnabled(5, (string)value != "Duration");
                props.SetPropertyEnabled(6, (string)value == "Duration");
            }
            else if (propIdx == 7)
            {
                var separateChannels = (bool)value;

                props.SetPropertyEnabled(9, !separateChannels);
                if (separateChannels)
                {
                    props.SetPropertyValue(9, false);
                }

                props.SetColumnEnabled(10, 2, props.GetPropertyValue <bool>(9));
            }
            else if (propIdx == 9)
            {
                props.SetColumnEnabled(10, 2, (bool)value);
            }
        }
예제 #3
0
        private void MappingProperties_PropertyChanged(PropertyPage props, int idx, object value)
        {
            var sourceType = MidiSourceType.GetValueForName(props.GetPropertyValue <string>(0));

            if (idx == 0)
            {
                props.UpdateDropDownListItems(1, GetSourceNames(sourceType));
            }

            var allowChannel10Mapping = false;

            if (sourceType == MidiSourceType.Channel)
            {
                var channelIdx = int.Parse(props.GetPropertyValue <string>(1).Substring(8)) - 1;
                allowChannel10Mapping = channelIdx == 9;
            }

            props.SetPropertyEnabled(1, sourceType != MidiSourceType.None);
            props.SetPropertyEnabled(3, sourceType != MidiSourceType.None && allowChannel10Mapping);
            props.SetPropertyEnabled(4, sourceType != MidiSourceType.None && allowChannel10Mapping);
            props.SetPropertyEnabled(5, sourceType != MidiSourceType.None && allowChannel10Mapping);
        }
예제 #4
0
        private void Properties_PropertyChanged(PropertyPage props, int idx, object value)
        {
            if (inPropertyChanged)
            {
                return;
            }

            inPropertyChanged = true; // Prevent recursion.

            if (idx == 1)
            {
                bool allEffects = (bool)value;

                foreach (var kv in propToEffect)
                {
                    props.SetPropertyValue(kv.Key, allEffects);
                }
            }
            else if (propToEffect.ContainsKey(idx))
            {
                bool allEffects = true;

                foreach (var kv in propToEffect)
                {
                    if (!props.GetPropertyValue <bool>(kv.Key))
                    {
                        allEffects = false;
                        break;
                    }
                }

                props.SetPropertyValue(1, allEffects);
            }

            inPropertyChanged = false;
        }
예제 #5
0
        private void UpdateWarnings()
        {
            var numFramesPerPattern = 0;

            if (song.UsesFamiStudioTempo)
            {
                var tempoIndex      = Array.IndexOf(tempoStrings, props.GetPropertyValue <string>(famistudioBpmPropIdx));
                var tempoInfo       = tempoList[tempoIndex];
                var notesPerBeat    = props.GetPropertyValue <int>(notesPerBeatPropIdx);
                var notesPerPattern = props.GetPropertyValue <int>(notesPerPatternPropIdx);

                if (tempoInfo.groove.Length == 1)
                {
                    props.SetPropertyWarning(famistudioBpmPropIdx, CommentType.Good, "Ideal tempo : notes will be perfectly evenly divided.");
                }
                else if ((tempoInfo.groove.Length % notesPerBeat) == 0 ||
                         (notesPerBeat % tempoInfo.groove.Length) == 0)
                {
                    props.SetPropertyWarning(famistudioBpmPropIdx, CommentType.Warning, "Beat-aligned groove : notes will be slightly uneven, but well aligned with the beat.");
                }
                else
                {
                    props.SetPropertyWarning(famistudioBpmPropIdx, CommentType.Error, "Unaligned groove : notes will be slightly uneven and not aligned to the beat.");
                }

                if (notesPerBeat != 4)
                {
                    props.SetPropertyWarning(notesPerBeatPropIdx, CommentType.Error, "A value of 4 is strongly recommended as it gives the best range of available BPMs.");
                }
                else
                {
                    props.SetPropertyWarning(notesPerBeatPropIdx, CommentType.Good, "4 is the recommended value.");
                }

                var groovePadMode = GroovePaddingType.GetValueForName(props.GetPropertyValue <string>(groovePadPropIdx));
                numFramesPerPattern = FamiStudioTempoUtils.ComputeNumberOfFrameForGroove(notesPerPattern * Utils.Min(tempoInfo.groove), tempoInfo.groove, groovePadMode);
            }
            else if (famitrackerSpeedPropIdx >= 0)
            {
                var speed = props.GetPropertyValue <int>(famitrackerSpeedPropIdx);
                var tempo = props.GetPropertyValue <int>(famitrackerTempoPropIdx);

                if (speed == 1)
                {
                    props.SetPropertyWarning(famitrackerSpeedPropIdx, CommentType.Warning, $"A speed of 1 will not produce the same BPM between platforms (PAL/NTSC).");
                }
                else
                {
                    props.SetPropertyWarning(famitrackerSpeedPropIdx, CommentType.Good, "");
                }

                if (tempo != 150)
                {
                    props.SetPropertyWarning(famitrackerTempoPropIdx, CommentType.Warning, "A tempo of 150 is strongly recommended as it produces even notes on all platforms (NTSC/PAL).");
                }
                else
                {
                    props.SetPropertyWarning(famitrackerTempoPropIdx, CommentType.Good, "150 is the recommended value.");
                }
            }

            if (patternIdx >= 0 && numFramesPerPattern > song.PatternLength)
            {
                props.SetPropertyWarning(notesPerPatternPropIdx, CommentType.Warning, $"Pattern is longer than the song pattern length and FamiTracker does not support this. Ignore this if you are not planning to export to FamiTracker.");
            }
            else if (numFramesPerPattern >= 256)
            {
                props.SetPropertyWarning(notesPerPatternPropIdx, CommentType.Warning, $"Pattern is longer than what FamiTracker supports. Ignore this if you are not planning to export to FamiTracker.");
            }
            else
            {
                props.SetPropertyWarning(notesPerPatternPropIdx, CommentType.Good, "");
            }
        }
예제 #6
0
        private void Properties_PropertyChanged(PropertyPage props, int propIdx, int rowIdx, int colIdx, object value)
        {
            if (propIdx == 4)
            {
                var expansionMask   = GetExpansionMask(props.GetPropertyValue <bool[]>(4));
                var newChannelCount = Channel.GetChannelCountForExpansionMask(expansionMask, 8);
                var oldChannelCount = channelSources.Length;

                var maxChannelIndex = 2;
                for (int i = 0; i < oldChannelCount; i++)
                {
                    if (channelSources[i].type == MidiSourceType.Channel && channelSources[i].index != 9)
                    {
                        maxChannelIndex = Math.Max(maxChannelIndex, channelSources[i].index);
                    }
                }

                Array.Resize(ref channelSources, newChannelCount);

                for (int i = oldChannelCount; i < newChannelCount; i++)
                {
                    maxChannelIndex = Math.Min(maxChannelIndex + 1, 15);
                    if (maxChannelIndex == 9)
                    {
                        maxChannelIndex++;
                    }
                    channelSources[i] = new MidiFileReader.MidiSource()
                    {
                        index = maxChannelIndex
                    };
                }

                UpdateListView();

                bool allowPal = expansionMask == ExpansionType.NoneMask;
                dialog.Properties.SetPropertyEnabled(3, allowPal);
                if (!allowPal)
                {
                    dialog.Properties.SetPropertyValue(3, false);
                }
            }
            else if (propIdx == 6)
            {
                Debug.Assert(colIdx == 1);

                var src = channelSources[rowIdx];
                var str = (string)value;

                if (str.StartsWith("Track"))
                {
                    src.type  = MidiSourceType.Track;
                    src.index = Utils.ParseIntWithTrailingGarbage(str.Substring(6)) - 1;
                }
                else if (str.StartsWith("Channel"))
                {
                    src.type  = MidiSourceType.Channel;
                    src.index = Utils.ParseIntWithTrailingGarbage(str.Substring(8)) - 1;
                }
                else
                {
                    src.type  = MidiSourceType.None;
                    src.index = 0;
                }

                UpdateListView();
            }
        }