musicLineアプリ開発日記

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

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

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

指ツールの動作


実装状況
カテゴリタイトル補足
View
Composition
UI配置
ガイド表示
連符連符は数字で表示、拡大率によって省略
Composition
Common
作曲共通
データ構造座標とサイズ、状態を保持する。レンダラーやコライダー、通知等のロジック
コンバーターDomainのデータ構造へ変換・逆変換
FingerTool
指ツール
音符の編集
データ構造基点と移動ベクトルを保持して移動する
音符の移動和音や連符は上下のみに制御
音符の影移動中に操作できているかわかりやすいように(iOS独自)
内外判定音符の移動をフレーズ内に留める
衝突判定移動する音符が他の音符に重なったときの挙動
タップ選択タップした音符の子音符も選択・解除
矩形選択囲った音符を選択
音符の入れ替えリズム音符のスライドで重なった音符と入れ替える(iOS独自)
和音の削除和音を移動した時に重なる時に削除する
連符に切り替えリズム音符タップで切り替え
Transform
画面移動
座標変換
画面を拡大・縮小(軸指定)長押しからのドラッグ。ピアノでX軸方向、スクロールエリアでY軸方向
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ファイルを再生する
リポジトリ保存データを管理


全進捗マップを表示

カテゴリタイトル補足
View
Composition
UI配置
ガイド表示
ピアノ
スクロールエリア
小節番号
小節線
分割線拡大率によって間隔を変化
フレーズフレーズがないところはフレーズ作成ボタンを表示
ツールボタン ボタンの処理は未実装。色はデフォルトを使用
メロディーライン ペンツールでの音符作成時の入力線
メロディー音符 音符の先頭にチョボをつける
リズム音符 ベース音符のみ下に表示 画面外に音符が出ると消える不具合がある
サンプルデータ 手入力したサンプルデータの音符を配置
連符連符は数字で表示、拡大率によって省略
Community
UI配置
Composition
Common
作曲共通
データ構造座標とサイズ、状態を保持する。レンダラーやコライダー、通知等のロジック
コンバーターDomainのデータ構造へ変換・逆変換
FingerTool
指ツール
音符の編集
データ構造基点と移動ベクトルを保持して移動する
音符の移動和音や連符は上下のみに制御
音符の影移動中に操作できているかわかりやすいように(iOS独自)
内外判定音符の移動をフレーズ内に留める
衝突判定移動する音符が他の音符に重なったときの挙動
タップ選択タップした音符の子音符も選択・解除
矩形選択囲った音符を選択
音符の入れ替えリズム音符のスライドで重なった音符と入れ替える(iOS独自)
和音の削除和音を移動した時に重なる時に削除する
連符に切り替えリズム音符タップで切り替え
PenTool
ペンツール
音符の作成
EraserTool
消しゴムツール
音符の削除
PhraseTool
フレーズツール
フレーズの編集
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ファイルを再生する
リポジトリ保存データを管理


指ツールの実装

音符の移動と影

メロディー音符をスワイプした時に、音符を移動します。子音符(和音や連符)がある時は、子音符も一緒に移動します。
なお、和音と連符を移動する時は上下方向のみに制御しており、和音はベース音符(下の音符)より下に行かないようにしています。ルート音符(左下の音符)は上下左右に移動します。

音符の移動

また、移動時には音符の影を付けました。音符は五線譜上に並ぶため、カクカクと移動したり、音符が重なるところに移動できなかったりするので、今操作できていることが分かりやすいように、ガイドとして影を付けています。


内外判定

移動時にフレーズ外に音符が出ないようにしました。
現在、移動している音符とフレーズで内か外かを判定して、音符がフレーズ外に出ている時はフレーズ内に収まるベクトルを算出しています。

フレーズとの内外判定

なお、移動している音符の子音符(和音や連符)や選択している音符がある場合、その音符も含めて外形で判定することでフレーズの外に出さないようにしています。


衝突判定

移動時に他の音符と重ならないようにしました。
移動後の場所に音符がある場合、その音符を避けるように移動します。移動できるスペースが左右で複数ある場合は、音符の影(移動するはずの位置)から近い方に移動します。なお、左右のスペースがない場合は移動しません。

他の音符との衝突判定

そもそもなぜこの仕様? musicLineではペンツールでメロディーを入力して音符を作成しますが、この入力のためY軸上に複数の音符があると、ペンツールの動作が一意に決まらなくなるため、重複しない仕様となっています。
(この仕様が使いづらいというご指摘が多々ありますが。。将来的に入力方法を見直すかも ; )


タップ選択

音符をタップすることで選択・選択解除します。
なお、ルート音符やベース音符をタップした時は、その子音符(和音や連符)も選択・選択解除の対象となります。音符外の空白をタップすると全選択解除になります。

タップでの音符選択

ちなみに、音符内を正確にタップしなくても、一定の距離以内であればタップ位置から一番近い音符を選択するようになっています。なお、距離はタップ位置から音符の枠までの距離を算出しています。(点と四角形との距離)


矩形選択

囲った音符を選択します。
矩形選択もタップ選択と同様、子音符があればその音符も選択の対象となります。

矩形による音符選択

なお、矩形から出た音符は矩形に入る前の選択状態に戻ります。そのため、選択音符を広げていく方法以外にも、全体を囲って選択音符を狭めていく方法もできます。


音符の入れ替え

リズム音符をスワイプすることで音符の位置を入れ替えます。
メロディー音符で移動する場合は、衝突する音符を避けるように配置しますが、リズム音符で移動する場合は、位置を入れ替えるようにしています。

音符の入れ替え

試しにこの機能を付けてみましたが、需要はないかも?


和音の削除

和音を移動した時に重なる音符があると削除します。

和音の削除

和音の追加も簡単にできるようにしたいですね。
Androidでは選択してツールプロパティバーから和音追加ボタンを押して追加していますが、もっと直感的に和音を追加できてもいいかも。


連符に切り替えと連符の表示

リズム音符をタップして連符に切り替えます。
デフォルトは三連符です。

連符に切り替え

また、連符は数字で表示します。拡大率によって、数字や白点を省略します。

連符の表示



おわりに

前回の進捗状況がぱっと見で分かりずらいと思ったので、今回はちゃんと表にしてみました。
なかなかいいペースで進んでいますね===\^ o ^ /

さて、今回は指ツールの実装ばかりを紹介しましたが(わかりやすいので。。)、実際はCompositionとDomainのデータ構造を考えることを重点的に取り組みました。Domainでは作曲データを保存する構造で、Compositionは作曲する時に最適なデータ構造となっています。

詳細はこちら(わかりずらいですが;)

今後はペンツールの実装を進めていきたいと思います。

あとAndroidの方もそろそろアップデートしないと。