void Awake() { increaseButton.AddListener(EventTriggerType.PointerUp, e => _operateSpinButtonObservable.OnNext(0)); decreaseButton.AddListener(EventTriggerType.PointerUp, e => _operateSpinButtonObservable.OnNext(0)); increaseButton.AddListener(EventTriggerType.PointerDown, e => _operateSpinButtonObservable.OnNext(valueStep)); decreaseButton.AddListener(EventTriggerType.PointerDown, e => _operateSpinButtonObservable.OnNext(-valueStep)); var property = GetReactiveProperty(); property.Subscribe(x => inputField.text = x.ToString()); //float temp = 0f; var updateValueFromInputFieldStream = inputField.OnValueChangedAsObservable() //.Where(x => Regex.IsMatch(x, @"^[0-9]+$")) .Select(x => { var temp = 0f; if (float.TryParse(x, out temp)) { return(temp); } return(property.Value); }); var updateValueFromSpinButtonStream = _operateSpinButtonObservable //.Throttle(TimeSpan.FromMilliseconds(longPressTriggerMilliseconds)) //.Where(delta => Math.Abs(delta) > float.Epsilon) //.SelectMany(delta => Observable.Interval(TimeSpan.FromMilliseconds(continuousPressIntervalMilliseconds)) // .TakeUntil(_operateSpinButtonObservable.Where(d => Math.Abs(d) <= float.Epsilon)) // .Select(_ => delta)) //.Merge(_operateSpinButtonObservable.Where(d => Math.Abs(d) > float.Epsilon)) .Select(delta => property.Value + delta); var isUndoRedoAction = false; Observable.Merge( updateValueFromSpinButtonStream, updateValueFromInputFieldStream) .Select(x => Mathf.Clamp(x, minValue, maxValue)) .DistinctUntilChanged() .Where(_ => isUndoRedoAction ? (isUndoRedoAction = false) : true) .Select(x => new { current = x, prev = property.Value }) .Subscribe(x => EditCommandManager.Do( new Command( () => property.Value = x.current, () => { isUndoRedoAction = true; property.Value = x.prev; }, () => { isUndoRedoAction = true; property.Value = x.current; }))) .AddTo(this); }
IEnumerator LoadMusic(string fileName) { using (var _unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(Path.Combine(MusicSelector.DirectoryPath.Value, fileName), AudioType.WAV)){ yield return(_unityWebRequest.SendWebRequest()); EditCommandManager.Clear(); ResetEditor(); AudioClip clip = null; if (_unityWebRequest.isHttpError || _unityWebRequest.isNetworkError) { Debug.Log(_unityWebRequest.error.ToString()); } else { clip = DownloadHandlerAudioClip.GetContent(_unityWebRequest); Audio.Source.clip = clip; EditData.Name.Value = fileName; LoadEditData(); Audio.OnLoad.OnNext(Unit.Default); } } /* * using (var www = new WWW("file:///" + Path.Combine(MusicSelector.DirectoryPath.Value, fileName))) * { * yield return www; * * EditCommandManager.Clear(); * ResetEditor(); * Audio.Source.clip = www.GetAudioClip(); * * if (Audio.Source.clip == null) * { * // TODO: 読み込み失敗時の処理 * } * else * { * EditData.Name.Value = fileName; * LoadEditData(); * Audio.OnLoad.OnNext(Unit.Default); * } * } */ }
void Init() { var handlerOnMouseDownObservable = new Subject <Vector3>(); handleImage.AddListener( EventTriggerType.PointerDown, (e) => { handlerOnMouseDownObservable.OnNext(Vector3.right * ConvertUtils.SamplesToCanvasPositionX(CurrentSamples.Value)); }); var operateHandleObservable = this.UpdateAsObservable() .SkipUntil(handlerOnMouseDownObservable) .TakeWhile(_ => !Input.GetMouseButtonUp(0)) .RepeatSafe() .Select(_ => ConvertUtils.ScreenToCanvasPosition(Input.mousePosition)) .Select(canvasPos => ConvertUtils.CanvasPositionXToSamples(canvasPos.x)) .Select(samples => Mathf.Clamp(samples, 0, Audio.Source.clip.samples)) .DistinctUntilChanged(); operateHandleObservable.Subscribe(samples => CurrentSamples.Value = samples); operateHandleObservable.Buffer(this.UpdateAsObservable().Where(_ => Input.GetMouseButtonUp(0))) .Where(b => 2 <= b.Count) .Select(x => new { current = x.Last(), prev = x.First() }) .Subscribe(x => EditCommandManager.Do( new Command( () => CurrentSamples.Value = x.current, () => CurrentSamples.Value = x.prev))); Observable.Merge( CurrentSamples.AsUnitObservable(), NoteCanvas.OffsetX.AsUnitObservable(), Audio.SmoothedTimeSamples.AsUnitObservable(), NoteCanvas.Width.AsUnitObservable(), EditData.OffsetSamples.AsUnitObservable()) .Select(_ => CurrentSamples.Value) .Subscribe(x => { var pos = lineRectTransform.localPosition; pos.x = ConvertUtils.SamplesToCanvasPositionX(x); lineRectTransform.localPosition = pos; }); }
IEnumerator LoadMusic(string fileName) { using (var www = new WWW("file:///" + Path.Combine(MusicSelector.DirectoryPath.Value, fileName))) { yield return(www); EditCommandManager.Clear(); ResetEditor(); Audio.Source.clip = www.GetAudioClip(); if (Audio.Source.clip == null) { // TODO: 読み込み失敗時の処理 } else { EditData.Name.Value = fileName; LoadEditData(); Audio.OnLoad.OnNext(Unit.Default); } } }
void Init() { var operateCanvasScaleObservable = canvasEvents.MouseScrollWheelObservable .Where(_ => KeyInput.CtrlKey()) .Merge(this.UpdateAsObservable().Where(_ => Input.GetKey(KeyCode.UpArrow)).Select(_ => 0.05f)) .Merge(this.UpdateAsObservable().Where(_ => Input.GetKey(KeyCode.DownArrow)).Select(_ => - 0.05f)) .Select(delta => NoteCanvas.Width.Value * (1 + delta)) .Select(x => x / (Audio.Source.clip.samples / 100f)) .Select(x => Mathf.Clamp(x, 0.1f, 2f)) .Merge(canvasWidthScaleController.OnValueChangedAsObservable() .DistinctUntilChanged()) .DistinctUntilChanged() .Select(x => Audio.Source.clip.samples / 100f * x); operateCanvasScaleObservable.Subscribe(x => NoteCanvas.Width.Value = x); operateCanvasScaleObservable.Buffer(operateCanvasScaleObservable.ThrottleFrame(2)) .Where(b => 2 <= b.Count) .Select(x => new { current = x.Last(), prev = x.First() }) .Subscribe(x => EditCommandManager.Do( new Command( () => NoteCanvas.Width.Value = x.current, () => NoteCanvas.Width.Value = x.prev))); }
void Awake() { // Initialize canvas offset x Audio.OnLoad.Subscribe(_ => NoteCanvas.OffsetX.Value = -Screen.width * 0.45f * NoteCanvas.ScaleFactor.Value); var operateCanvasOffsetXObservable = this.UpdateAsObservable() .SkipUntil(canvasEvents.VerticalLineOnMouseDownObservable) .TakeWhile(_ => !Input.GetMouseButtonUp(0)) .Select(_ => Input.mousePosition.x) .Buffer(2, 1).Where(b => 2 <= b.Count) .RepeatSafe() .Select(b => (b[1] - b[0]) * NoteCanvas.ScaleFactor.Value) .Select(x => x + NoteCanvas.OffsetX.Value) .Select(x => new { x, max = Screen.width * 0.5f * 0.95f * NoteCanvas.ScaleFactor.Value }) .Select(v => Mathf.Clamp(v.x, -v.max, v.max)) .DistinctUntilChanged(); operateCanvasOffsetXObservable.Subscribe(x => NoteCanvas.OffsetX.Value = x); operateCanvasOffsetXObservable.Buffer(this.UpdateAsObservable().Where(_ => Input.GetMouseButtonUp(0))) .Where(b => 2 <= b.Count) .Select(x => new { current = x.Last(), prev = x.First() }) .Subscribe(x => EditCommandManager.Do( new Command( () => NoteCanvas.OffsetX.Value = x.current, () => NoteCanvas.OffsetX.Value = x.prev))); NoteCanvas.OffsetX.Subscribe(x => { var pos = verticalLineRect.localPosition; var pos2 = waveformRenderImage.localPosition; pos.x = pos2.x = x; verticalLineRect.localPosition = pos; waveformRenderImage.localPosition = pos2; }); }
void Init() { var closestNoteAreaOnMouseDownObservable = canvasEvents.NotesRegionOnMouseDownObservable .Where(_ => !KeyInput.CtrlKey()) .Where(_ => !Input.GetMouseButtonDown(1)) .Where(_ => 0 <= NoteCanvas.ClosestNotePosition.Value.num); closestNoteAreaOnMouseDownObservable .Where(_ => EditState.NoteType.Value == NoteTypes.Single) .Where(_ => !KeyInput.ShiftKey()) .Merge(closestNoteAreaOnMouseDownObservable .Where(_ => EditState.NoteType.Value == NoteTypes.Long)) .Subscribe(_ => { if (EditData.Notes.ContainsKey(NoteCanvas.ClosestNotePosition.Value)) { EditData.Notes[NoteCanvas.ClosestNotePosition.Value].OnClickObservable.OnNext(Unit.Default); } else { RequestForEditNote.OnNext( new Note( NoteCanvas.ClosestNotePosition.Value, EditState.NoteType.Value, NotePosition.None, EditState.LongNoteTailPosition.Value)); } }); // Start editing of long note closestNoteAreaOnMouseDownObservable .Where(_ => EditState.NoteType.Value == NoteTypes.Single) .Where(_ => KeyInput.ShiftKey()) .Do(_ => EditState.NoteType.Value = NoteTypes.Long) .Subscribe(_ => RequestForAddNote.OnNext( new Note( NoteCanvas.ClosestNotePosition.Value, NoteTypes.Long, NotePosition.None, NotePosition.None))); // Finish editing long note by press-escape or right-click this.UpdateAsObservable() .Where(_ => EditState.NoteType.Value == NoteTypes.Long) .Where(_ => Input.GetKeyDown(KeyCode.Escape) || Input.GetMouseButtonDown(1)) .Subscribe(_ => EditState.NoteType.Value = NoteTypes.Single); var finishEditLongNoteObservable = EditState.NoteType.Where(editType => editType == NoteTypes.Single); finishEditLongNoteObservable.Subscribe(_ => EditState.LongNoteTailPosition.Value = NotePosition.None); RequestForRemoveNote.Buffer(RequestForRemoveNote.ThrottleFrame(1)) .Select(b => b.OrderBy(note => note.position.ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value)).ToList()) .Subscribe(notes => EditCommandManager.Do( new Command( () => notes.ForEach(RemoveNote), () => notes.ForEach(AddNote)))); RequestForAddNote.Buffer(RequestForAddNote.ThrottleFrame(1)) .Select(b => b.OrderBy(note => note.position.ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value)).ToList()) .Subscribe(notes => EditCommandManager.Do( new Command( () => notes.ForEach(AddNote), () => notes.ForEach(RemoveNote)))); RequestForChangeNoteStatus.Select(note => new { current = note, prev = EditData.Notes[note.position].note }) .Buffer(RequestForChangeNoteStatus.ThrottleFrame(1)) .Select(b => b.OrderBy(note => note.current.position.ToSamples(Audio.Source.clip.frequency, EditData.BPM.Value)).ToList()) .Subscribe(notes => EditCommandManager.Do( new Command( () => notes.ForEach(x => ChangeNoteStates(x.current)), () => notes.ForEach(x => ChangeNoteStates(x.prev))))); RequestForEditNote.Subscribe(note => { if (note.type == NoteTypes.Single) { (EditData.Notes.ContainsKey(note.position) ? RequestForRemoveNote : RequestForAddNote) .OnNext(note); } else if (note.type == NoteTypes.Long) { if (!EditData.Notes.ContainsKey(note.position)) { RequestForAddNote.OnNext(note); return; } var noteObject = EditData.Notes[note.position]; (noteObject.note.type == NoteTypes.Long ? RequestForRemoveNote : RequestForChangeNoteStatus) .OnNext(noteObject.note); } }); }
void Init() { this.UpdateAsObservable() .Where(_ => Audio.Source.clip != null) .Select(_ => Audio.Source.clip.samples) .Subscribe(samples => playbackPositionController.maxValue = samples); // Input -> Audio timesamples -> Model timesamples -> UI // Input (arrow key) var operateArrowKeyObservable = Observable.Merge( this.UpdateAsObservable().Where(_ => Input.GetKey(KeyCode.RightArrow)).Select(_ => 7), this.UpdateAsObservable().Where(_ => Input.GetKey(KeyCode.LeftArrow)).Select(_ => - 7)) .Select(delta => delta * (KeyInput.CtrlKey() ? 5 : 1)) .Select(delta => delta / NoteCanvas.Width.Value * NoteCanvas.ScaleFactor.Value * Audio.Source.clip.samples) .Select(delta => Audio.Source.timeSamples + delta); operateArrowKeyObservable.Where(_ => Audio.IsPlaying.Value) .Do(_ => Audio.IsPlaying.Value = false) .Subscribe(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value = true); operateArrowKeyObservable.Where(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value) .Throttle(TimeSpan.FromMilliseconds(50)) .Do(_ => Audio.IsPlaying.Value = true) .Subscribe(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value = false); // Input (scroll pad) var operateScrollPadObservable = this.UpdateAsObservable() .SkipUntil(canvasEvents.WaveformRegionOnMouseDownObservable .Where(_ => !Input.GetMouseButtonDown(1))) .TakeWhile(_ => !Input.GetMouseButtonUp(0)) .Select(_ => Input.mousePosition.x) .Buffer(2, 1).Where(b => 2 <= b.Count) .RepeatSafe() .Select(b => (b[0] - b[1]) / NoteCanvas.Width.Value * NoteCanvas.ScaleFactor.Value * Audio.Source.clip.samples) .Select(delta => Audio.Source.timeSamples + delta); canvasEvents.WaveformRegionOnMouseDownObservable .Where(_ => Audio.IsPlaying.Value) .Do(_ => Audio.IsPlaying.Value = false) .Subscribe(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value = true); this.UpdateAsObservable() .Where(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value) .Where(_ => Input.GetMouseButtonUp(0)) .Do(_ => Audio.IsPlaying.Value = true) .Subscribe(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value = false); // Input (mouse scroll wheel) var operateMouseScrollWheelObservable = canvasEvents.MouseScrollWheelObservable .Where(_ => !KeyInput.CtrlKey()) .Select(delta => Audio.Source.clip.samples / 100f * -delta) .Select(deltaSamples => Audio.Source.timeSamples + deltaSamples); operateMouseScrollWheelObservable.Where(_ => Audio.IsPlaying.Value) .Do(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value = true) .Subscribe(_ => Audio.IsPlaying.Value = false); operateMouseScrollWheelObservable.Throttle(TimeSpan.FromMilliseconds(350)) .Where(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value) .Do(_ => EditState.IsOperatingPlaybackPositionDuringPlay.Value = false) .Subscribe(_ => Audio.IsPlaying.Value = true); var isRedoUndoAction = false; // Input (slider) var operatePlayPositionSliderObservable = playbackPositionController.OnValueChangedAsObservable() .DistinctUntilChanged(); // Input -> Audio timesamples var operatePlaybackPositionObservable = Observable.Merge( operateArrowKeyObservable, operateScrollPadObservable, operateMouseScrollWheelObservable, operatePlayPositionSliderObservable) .Select(timeSamples => Mathf.FloorToInt(timeSamples)) .Select(timeSamples => Mathf.Clamp(timeSamples, 0, Audio.Source.clip.samples - 1)); operatePlaybackPositionObservable.Subscribe(timeSamples => Audio.Source.timeSamples = timeSamples); operatePlaybackPositionObservable.Buffer(operatePlaybackPositionObservable.ThrottleFrame(10)) .Where(_ => isRedoUndoAction ? (isRedoUndoAction = false) : true) .Where(b => 2 <= b.Count) .Select(x => new { current = x.Last(), prev = x.First() }) .Subscribe(x => EditCommandManager.Do( new Command( () => Audio.TimeSamples.Value = x.current, () => { isRedoUndoAction = true; Audio.TimeSamples.Value = x.prev; }, () => { isRedoUndoAction = true; Audio.TimeSamples.Value = x.current; }))); // Audio timesamples -> Model timesamples Audio.Source.ObserveEveryValueChanged(audio => audio.timeSamples) .DistinctUntilChanged() .Subscribe(timeSamples => Audio.TimeSamples.Value = timeSamples); this.UpdateAsObservable() .Where(_ => Audio.Source.clip != null) .Where(_ => Audio.Source.timeSamples > Audio.Source.clip.samples - 1) .Subscribe(_ => Audio.IsPlaying.Value = false); // Model timesamples -> UI(slider) Audio.TimeSamples.Subscribe(timeSamples => playbackPositionController.value = timeSamples); // Model timesamples -> UI(text) Audio.TimeSamples.Select(_ => TimeSpan.FromSeconds(Audio.Source.time).ToString().Substring(3, 5)) .DistinctUntilChanged() .Select(elapsedTime => elapsedTime + " / " + TimeSpan.FromSeconds(Audio.Source.clip.samples / (float)Audio.Source.clip.frequency).ToString().Substring(3, 5)) .SubscribeToText(playbackTimeDisplayText); }