musicLineアプリ開発日記

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

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

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

ペンツールの動作


実装状況
カテゴリタイトル補足
View
Composition
UI配置
ガイド表示
ツールガイド(ペン)リズム音符の長さ編集ガイド、長くした時の削る範囲音符移動時、移動先の音階をわかりやすくする
ツールガイド(消しゴム)削除範囲
Composition
PenTool
ペンツール
音符の作成
データ構造音符を作成・分割・統合する
音符の作成タップで音符を作成。分割線に合わせて長さを決定
音符列の作成スワイプに沿って複数の音符を作成。音階変わる時に音符分割
有無判定タップやスワイプした縦ラインに既に音符があるか判定
音符の移動音符が既にある場合は、作成ではなく移動。一定距離進むと移動終了
音符の分割リズム音符をタップした時、音符を分割、メロディ線に沿ってY位置を動かす
音符の統合2つのリズム音符の間をタップした場合、音符を統合
音符の伸縮リズム音符を左右にスワイプすることで音符の長さを伸縮、始点で分割なし(仕様変更)
音符の消滅音符の伸縮をした時に長さが0になると削除する(iOS独自)
領域差演算音符伸縮で他の音符に重なる時は差演算して他の音符長さを削る
サンプリング補間素早くスワイプしても音符が移動できるようにサンプリング間を補間する
細かい音符分割線内の細かな音符を移動する挙動
EraserTool
消しゴムツール
音符の削除
Transform
画面移動
座標変換
画面を拡大・縮小(軸指定)長押しからのドラッグ。ピアノでX軸方向、スクロールエリアでY軸方向


全進捗マップを表示

カテゴリタイトル補足
View
Composition
UI配置
ガイド表示
ピアノ
スクロールエリア
小節番号
小節線
分割線拡大率によって間隔を変化
フレーズフレーズがないところはフレーズ作成ボタンを表示
ツールボタン 選択中のツールはツール色にハイライトする
メロディーライン ペンツールでの音符作成時の入力線
メロディー音符 音符の先頭にチョボをつける
リズム音符 ベース音符のみ下に表示 画面外に音符が出ると消える不具合を修正
サンプルデータ 手入力したサンプルデータの音符を配置
連符連符は数字で表示、拡大率によって省略
ツールガイド(ペン)長さ編集しているリズム音符、伸ばした時の削る範囲音符移動時、移動先の音階をわかりやすくする
ツールガイド(指)移動中の音符影、矩形選択の枠
ツールガイド(消しゴム)削除範囲
音符音階メロディ音符に音階表示
Community
UI配置
Composition
Common
作曲共通
データ構造座標とサイズ、状態を保持する。レンダラーやコライダー、通知等のロジック
コンバーターDomainのデータ構造へ変換・逆変換
FingerTool
指ツール
音符の編集
データ構造基点と移動ベクトルを保持して移動する
音符の移動和音や連符は上下のみに制御
音符の影移動中に操作できているかわかりやすいように(iOS独自)
内外判定音符の移動をフレーズ内に留める
衝突判定移動する音符が他の音符に重なったときの挙動
タップ選択タップした音符の子音符も選択・解除
矩形選択囲った音符を選択
音符の入れ替えリズム音符のスライドで重なった音符と入れ替える(iOS独自)
和音の削除和音を移動した時に重なる時に削除する
連符に切り替えリズム音符タップで切り替え
PenTool
ペンツール
音符の作成
データ構造音符を作成・分割・統合する
音符の作成タップで音符を作成。分割線に合わせて長さを決定
音符列の作成スワイプに沿って複数の音符を作成。音階変わる時に音符分割
有無判定タップやスワイプした縦ラインに既に音符があるか判定
音符の移動音符が既にある場合は、作成ではなく移動。一定距離進むと移動終了
音符の分割リズム音符をタップした時、音符を分割、メロディ線に沿ってY位置を動かす
音符の統合2つのリズム音符の間をタップした場合、音符を統合
音符の伸縮リズム音符を左右にスワイプすることで音符の長さを伸縮、始点で分割なし(仕様変更)
音符の消滅音符の伸縮をした時に長さが0になると削除する(iOS独自)
領域差演算音符伸縮で他の音符に重なる時は差演算して他の音符長さを削る
サンプリング補間素早くスワイプしても音符が移動できるようにサンプリング間を補間する
細かい音符分割線内の細かな音符を移動する挙動
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ファイルを再生する
リポジトリ保存データを管理


ペンツールの実装

音符の作成・移動

メロディ編集エリアをタップした時に、音符を作成します。タップした縦ラインに既に音符がある時は、その音符の音階を移動します。
なお、音符の長さは分割線に合わせた長さになります。より細かい音符を作成するときは、画面を拡大して分割線のピッチ幅を細かくします。

音符の作成・移動


音符列の作成

メロディ編集エリアをスワイプすると、スワイプ線に沿って複数の音符を作成します。音階が変わるタイミングで音符を分割します。
なお、既に音符がある時は長さは変わらず音階だけ移動します。

音符列の作成


有無判定

タップやスワイプ時、縦ラインに既に音符が存在するか判定します。
音符の有無判定は分割線を基準に(正確には分割線間の縦ラインに存在しているか)判定します。分割線内に細かな音符がある場合も、音符を作成せずに、既存の音符を移動します。

有無判定


音符の分割・統合

リズム音符をタップすることで音符を分割します。
なお、音符を分割するときは、メロディ線に沿って音階を移動します。
また、2つのリズム音符の間をタップすることで音符を統合します。

音符の分割・統合


音符の伸縮・消滅
ツールガイド(編集中のリズム音符)

リズム音符を左右にスワイプすることで音符の長さを変更します。
長さを変更している際、指でリズム音符が隠れないように上部にガイドを表示します。
音符の長さが 0 になるまで短くした時、音符は削除されます。

音符の伸縮・消滅

Androidの仕様 Androidではリズムを上書きするような仕様だったため、スワイプの始点で音符を分割してました。
これは音符長さを調整する仕様ではないため、特に音符の長さを短くする操作ができない課題がありました。
iOSでは仕様を見直し、音符長さの調整を適切にできるように仕様変更しました。
なお、タップで音符を分割してからスワイプすることで、従来のAndroidの仕様と同じような操作となります。


領域差演算
ツールガイド(削る領域)

音符の伸縮で他の音符に重なる時は差演算して、他の音符長さを削ります。

領域差演算

なお削れる領域がわかるように、音符の伸縮操作をしている時に削れる領域をグレーのガイドで表示します。


サンプリング補間

素早くスワイプするとサンプリング間が広くなり、操作が抜けることがあります。
その現象を回避するため、サンプリング間を補間します。

サンプリング補間

スワイプが早くても、またデバイスの動作が重くなっても安定してメロディを作成します。


細かい音符

基本的には分割線を基準に音符を作成したり、音符を操作しますが、分割線内に細かな音符がある場合、分割線に関わらず細かい音符を操作します。

細かい音符


画面を拡大・縮小(軸指定)

スクロールエリアやピアノエリアをロングタップ+スワイプすることで横軸と縦軸を分けた拡大縮小をします。

画面を拡大・縮小(軸指定)

iOSではピンチイン・アウトのジェスチャーで方向までは検知できないようなので、ピンチイン・アウトの場合は軸指定できないようになっています。



おわりに

ペンツールが思ったより苦戦しました。
実は指ツールの細かな不具合等もあり、長引きました。
でも不具合も修正できて、2大ツール(ペン・指)の実装が完了しました!

次は消しゴムツールの実装に取り掛かります。