-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
音量編集機能の追加 #2263
base: main
Are you sure you want to change the base?
音量編集機能の追加 #2263
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
音量編集機能の実装ありがとうございます!
| { type: "draw"; data: number[]; startFrame: number } | ||
| { type: "erase"; startFrame: number; frameLength: number } | ||
| undefined | ||
>(undefined); | ||
const prevCursorPos = { frame: 0, frequency: 0 }; // 前のカーソル位置 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ピッチ編集用のprevCursorPos
になっちゃっているので、
prevCursorPos: { frame: number; frequency: number; }
を無くして、
prevCursorFrame: number
と
prevCursorFrequency: number
と
prevCursorVolume: number
にするのが一旦良いかもと思いました!
@@ -667,6 +686,79 @@ const previewDrawPitch = () => { | |||
prevCursorPos.frequency = cursorFrequency; | |||
}; | |||
|
|||
// ピッチを描く処理を行う | |||
const previewDrawVolume = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
細かいですが、関数の順番は
- previewDrawPitch
- previewErasePitch
- previewDrawVolume
- previewEraseVolume
が良いかなと思いました!
(処理は似ていますが、一旦共通化はせずに個々の機能として分けておくのが良いかなと)
const cursorFrame = Math.round(cursorSeconds * frameRate); | ||
const cursorNoteNumber = baseYToNoteNumber(cursorBaseY, false); | ||
const cursorFrequency = noteNumberToFrequency(cursorNoteNumber); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは、cursorFrequency
を無くして、cursorVolume
を算出する処理を追加になるかなと思います。
以下のような感じでsing/viewHelper.ts
に変換処理を実装して、それを使用するのが良いと思います。(decibelToLinear
とlinearToDecibel
はsing/domain.ts
にあります)
// viewHelper.ts
const PIXELS_PER_DECIBEL = 6;
const DECIBEL_VIEW_OFFSET = 100;
export function viewYToDecibel(viewY: number) {
return -((viewY - DECIBEL_VIEW_OFFSET) / PIXELS_PER_DECIBEL);
}
export function decibelToViewY(decibel: number) {
return -decibel * PIXELS_PER_DECIBEL + DECIBEL_VIEW_OFFSET;
}
// ScoreSequencer.vue
const cursorDecibel = viewYToDecibel(cursorY.value);
const cursorVolume = decibelToLinear(cursorDecibel);
}; | ||
} else { | ||
throw new Error("Unknown preview mode."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここはeditTarget.value === "PITCH"
のときと同様に、最後に
prevCursorFrame = cursorFrame;
prevCursorVolume = cursorVolume;
する必要があるかも。
// 平滑化を行う | ||
let data = previewVolumeEdit.value.data; | ||
data = data.map((value) => Math.log(value)); | ||
applyGaussianFilter(data, 0.7); | ||
data = data.map((value) => Math.exp(value)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
一旦平滑化はなしで、配列のコピーのみで良いかも…!
const zoomX = store.state.sequencerZoomX; | ||
const zoomY = store.state.sequencerZoomY; | ||
const offsetX = props.offsetX; | ||
const offsetY = props.offsetY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
音量の線はシーケンサーを垂直方向にスクロールしたときに動かない方が良いかもです。なので、ここのzoomY
とoffsetY
は無くて良いかも。
const voiced = !unvoicedPhonemes.includes(phoneme); | ||
if (voiced && volumeEditData[i] !== VALUE_INDICATING_NO_DATA) { | ||
volume[i - singingGuideStartFrame] = volumeEditData[i]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ピッチではなく音量なので、voiced
の判定はしなくても良いかも。
SET_VOLUME_EDIT_DATA: { | ||
// ピッチ編集データをセットする。 | ||
// track.pitchEditDataの長さが足りない場合は、伸長も行う。 | ||
mutation(state, { volumeArray, startFrame, trackId }) { | ||
const track = getOrThrow(state.tracks, trackId); | ||
const pitchEditData = track.volumeEditData; | ||
const tempData = [...pitchEditData]; | ||
const endFrame = startFrame + volumeArray.length; | ||
if (tempData.length < endFrame) { | ||
const valuesToPush = new Array(endFrame - tempData.length).fill( | ||
VALUE_INDICATING_NO_DATA, | ||
); | ||
tempData.push(...valuesToPush); | ||
} | ||
tempData.splice(startFrame, volumeArray.length, ...volumeArray); | ||
track.volumeEditData = tempData; | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
処理がSET_PITCH_EDIT_DATA
と同じになってるかも。
ERASE_VOLUME_EDIT_DATA: { | ||
mutation(state, { startFrame, frameLength, trackId }) { | ||
const track = getOrThrow(state.tracks, trackId); | ||
const pitchEditData = track.pitchEditData; | ||
const tempData = [...pitchEditData]; | ||
const endFrame = Math.min(startFrame + frameLength, tempData.length); | ||
tempData.fill(VALUE_INDICATING_NO_DATA, startFrame, endFrame); | ||
track.pitchEditData = tempData; | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここも変更が必要かも。
@@ -1632,6 +1687,7 @@ export const singingStore = createPartialStore<SingingStoreTypes>({ | |||
// 歌い方をコピーして、ピッチ編集を適用する | |||
singingGuide = structuredClone(toRaw(singingGuide)); | |||
applyPitchEdit(singingGuide, track.pitchEditData, editFrameRate); | |||
applyVolumeEdit(singingGuide, track.pitchEditData, editFrameRate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここはtrack.volumeEditData
を渡す必要がありそう。
内容
音量をピッチと同様にカーブを描いて編集できるようにする。
ラインの色やアイコンは暫定
問題点
volumeData.dataにundefinedが含まれているため?
関連 Issue
#2003
スクリーンショット・動画など
ツールバー
全体