musicLineアプリ開発日記

作曲を誰でも楽しく簡単に♪

【iOS】作曲画面の進捗報告 5

musicLine(iOS)についての進捗。
フレーズツールの実装が大体完了したので報告します。

フレーズツールの動作
※ 描画に不具合があり、ちょっと変

ただし現在は描画に不具合があり、フレーズツールの操作がわかりづらくなっています。

例えば、フレーズダイアログで作成ボタンをタップしても反応がありません。正確に言えば実際はフレーズを作成したんだけど、画面の描画が行われずに作成できてないような表示になります。

描画タイミングの不具合
※ スクロールすると描画される

これはモデルの通知機構に問題があり、モデルの変更を適切に監視できてないことが要因になります。今後通知機構について見直していきます。

現在は、暫定処置として画面をスクロールすることで画面を強制的に描画しています。


実装状況
カテゴリタイトル補足
View
Composition
UI配置
ガイド表示
ツールガイド(フレーズ)フレーズ移動・伸縮のバー、選択範囲テキスト(iOS独自)
フレーズボタンフレーズボタンとサブボタンを配置、ツールに応じてアイコンを変更、画面拡大率に応じて縮小
フレーズタブツールに応じてアイコンを変更、拡大率に応じて縮小、スクロール状態に応じて移動
Dialog
ダイアログ
フレーズフレーズの作成・設定・挿入、フレーズの長さやリピート回数の設定
Composition
Common
作曲共通
通知機構Modelに変更があった時に、Viewへ通知して再描画。変更状況を監視してキャッシュ
PhraseTool
フレーズツール
フレーズの編集
データ構造トラックのフレーズを取得・追加、削除、状態 通知機構の実装を見直す。現状は一部描画がおかしい
フレーズの作成・挿入ダイアログで長さとリピートを設定 リピートフレーズは未実装
フレーズの選択2点タップで範囲選択、範囲ガイドタップで選択解除(仕様変更)
フレーズの移動左右スワイプで移動、移動は選択フレーズとスワイプ中のフレーズを含む
フレーズの伸縮サブ編集領域をスワイプした時にフレーズ長さを伸縮、長さ0で削除(iOS独自)
フレーズの貼り付け選択フレーズをコピー・ペースト、サブボタンかフレーズタブタップで挿入、選択解除
周囲有無判定作成する小節の近くにフレーズがあるかの判定、設定できる長さやリピート回数の制御
フレーズボタン・タブツールに応じてフレーズボタン、タブの処理を変更


全進捗マップを表示

カテゴリタイトル補足
View
Composition
UI配置
ガイド表示
ピアノ
スクロールエリア
小節番号
小節線
分割線拡大率によって間隔を変化
フレーズフレーズがないところはフレーズ作成ボタンを表示
ツールボタン 選択中のツールはツール色にハイライトする
メロディーライン ペンツールでの音符作成時の入力線
メロディー音符 音符の先頭にチョボをつける
リズム音符 ベース音符のみ下に表示
サンプルデータ 手入力したサンプルデータの音符を配置
連符連符は数字で表示、拡大率によって省略
ツールガイド(ペン)長さ編集しているリズム音符、伸ばした時の削る範囲音符移動時、移動先の音階をわかりやすくする
ツールガイド(指)移動中の音符影、矩形選択の枠
ツールガイド(消しゴム)削除範囲、和音のみの削除範囲
ツールガイド(フレーズ)フレーズ移動・伸縮のバー、選択範囲テキスト(iOS独自)
フレーズボタンフレーズボタンとサブボタンを配置、ツールに応じてアイコンを変更、画面拡大率に応じて縮小
フレーズタブツールに応じてアイコンを変更、拡大率に応じて縮小、スクロール状態に応じて移動
音符音階メロディ音符に音階表示
Community
UI配置
Dialog
ダイアログ
フレーズフレーズの作成・設定・挿入、フレーズの長さやリピート回数の設定
Composition
Common
作曲共通
データ構造座標とサイズ、状態を保持する。レンダラーやコライダー、通知等のロジック
コンバーターDomainのデータ構造へ変換・逆変換
通知機構Modelに変更があった時に、Viewへ通知して再描画。変更状況を監視してキャッシュ
FingerTool
指ツール
音符の編集
データ構造フレーズの音符を取得、基点と移動ベクトルを保持して移動する
音符の移動和音や連符は上下のみに制御
音符の影移動中に操作できているかわかりやすいように(iOS独自)
内外判定音符の移動をフレーズ内に留める
衝突判定移動する音符が他の音符に重なったときの挙動
タップ選択タップした音符の子音符も選択・解除
矩形選択囲った音符を選択
音符の入れ替えリズム音符のスライドで重なった音符と入れ替える(iOS独自)
和音の削除和音を移動した時に重なる時に削除する
連符に切り替えリズム音符タップで切り替え
PenTool
ペンツール
音符の作成
データ構造音符を作成・分割・統合、フレーズへ音符を追加する
音符の作成タップで音符を作成。分割線に合わせて長さを決定
音符列の作成スワイプに沿って複数の音符を作成。音階変わる時に音符分割
有無判定タップやスワイプした縦ラインに既に音符があるか判定
音符の移動音符が既にある場合は、作成ではなく移動。一定距離進むと移動終了
音符の分割リズム音符をタップした時、音符を分割、メロディ線に沿ってY位置を動かす
音符の統合2つのリズム音符の間をタップした場合、音符を統合
音符の伸縮リズム音符を左右にスワイプすることで音符の長さを伸縮、始点で分割なし(仕様変更)
音符の消滅音符の伸縮をした時に長さが0になると削除する(iOS独自)
領域差演算音符伸縮で他の音符に重なる時は差演算して他の音符長さを削る
サンプリング補間素早くスワイプしても音符が移動できるようにサンプリング間を補間する
細かい音符分割線内の細かな音符を移動する挙動
EraserTool
消しゴムツール
音符の削除
データ構造和音と連符の認識、フレーズから音符を削除する
音符の削除タップで音符を削除
和音・連符の削除和音・連符をタップで和音・連符のみを削除(iOS独自)
音符種別判定タップした音符が和音・連符・ルート音符なのか判定する
音符列の削除スワイプで指定する削除範囲内の複数の音符を削除。
和音列の削除リズム音符をスワイプで複数の和音のみを削除。(iOS独自)
休符に切り替えリズム音符タップで休符に切り替える
PhraseTool
フレーズツール
フレーズの編集
データ構造トラックのフレーズを取得・追加、削除、状態 通知機構の実装を見直す。現状は一部描画がおかしい
フレーズの作成・挿入ダイアログで長さとリピートを設定 リピートフレーズは未実装
フレーズの選択2点タップで範囲選択、範囲ガイドタップで選択解除(仕様変更)
フレーズの移動左右スワイプで移動、移動は選択フレーズとスワイプ中のフレーズを含む
フレーズの伸縮サブ編集領域をスワイプした時にフレーズ長さを伸縮、長さ0で削除(iOS独自)
フレーズの貼り付け選択フレーズをコピー・ペースト、サブボタンかフレーズタブタップで挿入、選択解除
周囲有無判定作成する小節の近くにフレーズがあるかの判定、設定できる長さやリピート回数の制御
フレーズボタン・タブツールに応じてフレーズボタン、タブの処理を変更
StampTool
スタンプツール
モチーフの編集
Transform
画面移動
座標変換
画面を上下移動ピアノのスワイプにより
画面を左右移動 スクロールエリアのスワイプにより
画面を拡大・縮小ピンチアウト・インにより基点を画面中心に設定する
画面を拡大・縮小(軸指定)長押しからのドラッグ。ピアノでX軸方向、スクロールエリアでY軸方向
MIDI
Common
MIDI共通
データ構造MIDIフォーマットへ出力できる構造
コンバーターCompositionのデータ構造へ変換・逆変換
Commnity
Common
コミュニティ
共通
データ構造カテゴリ等の曲情報、いいねやお気に入り等のリスポンスを保持
Domain
データ構造
Json形式
Melody MelodyTrack, *MelodyPhrase, NoteContainer, NoteBlock, Note
Drum DrumTrack, *DrumPhrase, BeatContainer, Beat
通化 Original, Repeat, Syncの3種のPhraseをジェネリッククラスとプロトコルで抽象化
Service
サービスモデル
SongRederJsonファイルを読み込み、Domainのデータへ変換
SongWriterDomainのデータからJsonファイルへ書き出し
Common
Service
サービスモデル
MidiPlayerMidiファイルを再生する
リポジトリ保存データを管理


フレーズツールの実装

フレーズの作成・挿入

フレーズボタンをタップした時に、フレーズを作成します。
フレーズの作成時にはダイアログを表示し、フレーズの長さやリピート回数を設定します。
また、フレーズサブボタンかフレーズタブをタップすることで、フレーズを挿入します。

フレーズの作成・挿入


フレーズの選択

フレーズをタップして選択します。
フレーズ外をタップすると選択解除になります。
なお、複数フレーズの飛び飛びでの選択はできず、2点タップすると2点間の範囲選択になります。

フレーズの選択

ちなみに、右上には選択しているフレーズの小節範囲が表示されます。その選択範囲のテキストをタップすることでも選択解除になります。


フレーズの移動

編集エリアを左右にスワイプして、フレーズを移動します。
フレーズを選択すると、複数のフレーズを一気に移動できます。
なお、選択フレーズとスワイプするフレーズの間にフレーズがある場合、挟まれたフレーズも一緒に移動します。

フレーズの移動

移動中は移動範囲がわかりやすいように、移動後の小節位置とバーを表示します。


フレーズの伸縮

サブ編集領域をスワイプすることで、フレーズの長さを伸縮します。
なおフレーズを短くした時、フレーズ外の音符は削除され、フレーズを跨いでいる音符は切断されます。
長さを0にすると、フレーズを削除します。

フレーズの伸縮


フレーズの貼り付け

フレーズボタンをタップすることで、選択フレーズをコピーして貼り付けます。
フレーズサブボタンかフレーズタブをタップすることで、選択フレーズをコピーして挿入します。
貼り付けた時、既にフレーズがある場合は上書きします。

フレーズの貼り付け


周囲有無判定

フレーズを作成する時、近くにフレーズがあるかを判定します。近くにフレーズがある場合、設定できる長さやリピート回数を制限します。

周囲有無判定

選択フレーズをコピペする際にも、周囲フレーズの有無を判定して、フレーズの上書きや選択解除の制御をします。

周囲有無判定(コピペ時)


フレーズボタン・タブ

ツールに応じてフレーズボタン等のアイコンや処理を変更します。

フレーズボタン・タブ

ツール ボタン サブボタン タブ
ペン フレーズ作成 - フレーズ設定
- - フレーズ内音符
全選択/解除
消しゴム 小節削除 - フレーズ削除
フレーズ
選択時
フレーズ作成
コピーペースト
フレーズ挿入
コピー挿入
フレーズ挿入
コピー挿入



おわりに

フレーズツールはとりあえず実装できました。
描画不具合があると、本当にできているかわかりづらいですが。。

なので次に行く前に、まずはモデル通知機構の見直しをします。
無理やりしようとすれば、ジェスチャ入力時に全てのViewを再描画することでも不具合解消になります。でも、描画コスト的に良くないですね。
描画は最小限に抑えないと音符が多くなったときに動作が重くなりそうなので、この辺りはちゃんと最適化しておきたいところです。
またモデル変更を適切に監視できていると、コストが高いMIDIファイル書き出し処理も最小限に抑えられる等の利点もあります。