9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Javascriptで作曲できる!(OngaqJS)

Last updated at Posted at 2020-12-11

この記事は ZOZOテクノロジーズ #2 Advent Calendar 2020 12日目の記事になります。

昨日の記事は @satto_sann の 「WSL2 + Ubuntu18.04 + Docker環境構築」です。

はじめに

今年ももう終わり...
そういえば1曲も作ってない!という焦燥感と、Adventカレンダーを書かなければいけない!という焦燥感を
同時に解消してくれるJavaScriptライブラリがありました。

\ OngaqJS /
https://www.ongaqjs.com/

まずは完成品から

https://soundcloud.com/cnbjpn/qiita
*音色は全てフリープランのものです。
*2小節のループを内部録音してからDAWでフェードアウトつけてます。

使い方

チュートリアルドキュメントがわかりやすかったので、
触りながら読み進めると良い感じです。

1.鳴らす楽器を決めて

const my_piano = new Part ({
    sound: "jazz_guitar"
})

2.鳴らすキー、タイミングや音量を決めて

my_piano.add( new Filter({
    key: ["D3","F3#","B4"],
    length: 6,
    measure: 1,
    volume: 40,
    active: (b,m) => b === 4 && m === 0|| b === 10 && m === 0|| b === 0 && m === 1
}))

3.鳴らす

ongaq.add(my_piano)

以下の部分は、

    key: ["D3","F3#","B4"],
    active: (b,m) => b === 4 && m === 0|| b === 10 && m === 0|| b === 0 && m === 1

ピアノロールにすると以下の譜面になります。
qiita.png

所感

チュートリアルも分かりやすく、意図したタイミングで音を鳴らせた瞬間が快感だったので興味ある方はぜひ触ってみてください!
今回は音を鳴らすまで試してみましたが、リファクタリングも楽しくできそうです。
MIDIの軽さを利用して、LPサイトなどへの仕掛けとして利用できれば面白そうですね。

今回の曲のサンプルコード

const ongaq = new Ongaq ({
    api_key: "***",
    volume: 100,
    bpm: 120,
    onReady: ()=>{

        const button = document.getElementById("button")
        button.className = "button start"
        button.onclick = () => {
            if (ongaq.params.isPlaying) {
                ongaq.pause()
                button.className = "button start"
            } else {
                ongaq.start()
                button.className = "button pause"
            }
        }
    }
})


//ドラムパート
const my_drums = new Part ({
    sound: "small_cube_drums"
})

my_drums.add( new Filter ({
    key: "kick",
    volume: 60,
    active: beat => beat % 8 === 0
}))

my_drums.add( new Filter({
    key: ["hihat"],
    volume: 50,
    active: n => n % 8 === 4
}))

my_drums.add( new Filter({
    key: ["snare"],
    volume: 40,
    active: n => n % 16 === 8
}))

my_drums.add( new Filter({
    key: ["tom2"],
    volume: 30,
    active: (n,m) => n % 16 === 2 && m % 2 === 0 || n % 16 === 6 && m % 2 === 0
}))


//メインパート
const my_piano = new Part ({
    sound: "jazz_guitar"
})

my_piano.add( new Filter({
    key: ["D2","D3","F3#","B4","D4"],
    length: 6,
    measure: 1,
    volume: 50,
    active: (b,m) => b === 4 && m === 0|| b === 10 && m === 0|| b === 0 && m === 1
}))

my_piano.add( new Filter({
    key: ["D2","D3","F3#","C4"],
    length: 5,
    measure: 1,
    volume: 48,
    active: (b,m) => b === 6 && m === 1|| b === 12 && m === 1
}))


my_piano.add( new Filter({
    key: ["C2","C3","E3","A4"],
    length: 6,
    measure: 3,
    volume: 50,
    active: (b,m) => b === 4 && m === 2|| b === 10 && m === 2|| b === 0 && m === 3 || b === 12 && m === 3
}))

my_piano.add( new Filter({
    key: ["C2","C3","E3","G4"],
    length: 5,
    measure: 3,
    volume: 40,
    active: (b,m) => b === 6 && m === 3
}))

const my_route = new Part({
    sound: "plain_keyboard"
})

my_route.add( new Filter({
    key: "G1",
    length: 4,
    measure: 3,
    volume: 30,
    active: (b,m) => b === 0 && m === 0 || b === 8 && m === 0 || b === 14 && m === 0
}))

const my_hit = new Part({
    sound: "violin"
})

my_hit.add( new Filter({
    key: ["D3","F3#","B4","D4"],
    length: 6,
    measure: 3,
    volume: 5,
    pan: 10,
    active: (b,m) => b % 8 === 0 && m <= 1
}) )

my_hit.add( new Filter({
    key: ["C3","E3","A4"],
    length: 6,
    measure: 3,
    volume: 5,
    active: (b,m) => b % 8 === 0 && m >= 2
}) )


my_hit.add( new Filter({
    type: "pan",
    x: 10
}))


const my_strings = new Part({
    sound: "poly_synth"
})

my_strings.add( new Filter({
    key: ["F3#","B4"],
    length: 32,
    measure: 5,
    volume: 2,
    active: (b,m) => b === 0 && m === 0
}))

my_strings.add( new Filter({
    key: ["E3","A4"],
    length: 32,
    measure: 5,
    volume: 2,
    active: (b,m) => b === 0 && m === 2
}))

my_strings.add( new Filter({
    type: "pan",
    x: -10
}))


//ベース
const my_monobass = new Part({
    sound: "mono_bass"
})

my_monobass.add( new Filter({
    key: "G1",
    length: 4,
    measure: 3,
    volume: 30,
    active: (beat,m) => beat % 8 === 4 && m <= 1
}))

my_monobass.add( new Filter({
    key: "F1",
    length: 4,
    measure: 3,
    volume: 30,
    active: (beat,m) => beat % 8 === 4 && m >= 2
}))


//音楽再生
ongaq.add(my_drums)
ongaq.add(my_piano)
ongaq.add(my_strings)
ongaq.add(my_hit)
ongaq.add(my_route)
ongaq.add(my_monobass)

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?