カテゴリー: テクノロジー

AIで音楽を作ってみました

こんにちは。開発担当のマットです。
このあいだ、友達を家に招いたら、楽器を持ってきました。
持ってきたものは、ディジュリドゥでした。

ディジュリドゥが母国のオーストラリアの先住民が使う吹奏楽器です。
子供の頃、叔父の家に一つあったのでちょっとだけ使ったことがありますが、
不慣れのディジュリドゥを吹いてみるとすぐに息が切れて、中々演奏できませんでした。

楽器を使って、音楽を作れたらカッコいいな〜と思ったら…

パソコンならできる?

実際の楽器なら演奏できる能力がない。
ただし、パソコンなら、ソフトウェアを使って、何かを作曲できそう!

と思ってみて、GarageBand という音楽制作ソフトを開いてみて、やってみたら・・・

なんじゃこれ・・・・完全に駄目ですね。真剣にやってみます。
GarageBand の使い方をなんとか勉強して、20分掛けてみたら、以下の曲を作れました。

なにこれ・・・w

壁が見えてきました

まず、GarageBand の音楽作成ソフトの使い方を覚えないといけない壁が一つ。
つぎ、音楽論など、音楽を作成する時に必要な最低限の知識を覚えないといけないので、壁が二つ。
そして、元々センスがない自分がなんとか、センスを付けないといけない壁が三つもあります。

難しいですね。

今どきの壁を破るAI

音楽なら、AIが作れますよね〜

ネットで探してみたら、多数の音楽生成のAIを見つけましたけど、自分が求めているものを見つけられませんでした。ほとんどのサービスが決められているテーマや楽器の組み合わせを使って、音楽を作れる便利なサービスですが、僕は求めていたのはクリエイティビティ。

・「背景を和太鼓にする」
・「テンポをちょっと落とす」
・「途中でバイオリンのソロを入れる」

など・・・このようなことをお願いしたら、やってくれるAIが欲しかったです。

話し相手を求めるなら・・・ChatGPT

このような人間の言葉を理解してくれるのは ChatGPT でしょう。
ChatGPT で完全に思う通りの音楽を作ってみることにしました。

まず、簡単な MIDI ファイルを作ってくれるようお願いしてみたら、以下の返答をもらいました。

「よかった!簡単にできる!」と思ったら、ChatGPT が嘘をついていました。
ファイルに保存して、.midi の拡張子を付けても、使い物になりませんでした。
よくよく調べてみたら、参考となった別のプロジェクトを見つけました。

全く別の形式なものを ChatGPT に作ってもらって、
それを pythonのライブラリーで変換しなければならない。

python で変換…(大変になってきた)

かなり、大変なことになってしまいましたが、Google Colab で python のスクリプトをコピーして、
ChatGPT に、新たな曲をその形式で求めて実行してみます。

ChatGPTのテキストをMIDIに変換するpython コード

ChatGPT に「複数な楽器を同時に演奏する曲」をお願いしてみました。
何度も何度も繰り返してみました。時には、フォーマットが不正な回答だった。
時には、複数の楽器の演奏があったけど、同時演奏ではなかったなど。

何度も頑張ってやったら、やっと、一つの曲をなんとか作れました。

フルートはかなりの耳障りですが・・・・ChatGPT に音楽を作ってもらったことでなんとか嬉しい気持ちです。

AIの未来

ChatGPT は言語専用のAIですが、実は Google の MusicFX も見つかりました。
日本では使えないツールですが、オーストラリアからアクセスしてみたら、ログインができて、使うことができました。

このツールを使えば、言葉だけで音楽を生成することができます。

まずは、
1)「Caribbean relaxing music with snare drums」(スネアドラムを使ったカリブ海風のくつろげる音楽)

次は、
2) 「Opera with Electric Guitars」(エレキギターを使ったオペラ)

最後は、もともと作りたかったもの
3) 「Rock and Roll with a Didgeridoo」(ディジュリドゥを使ったロックンロール)

まとめ

MusicFXの結果がかなり優れていて、びっくりはしましたけど、その反面、簡単な MIDI ファイルを作るだけでも大苦労でした。

今後、AIが進化するに連れ、このようなツールが数多くなって、力強くなると思います。
いずれ、僕のような音楽の初心者でも、完全にいいものを作曲できる日を楽しみにしています。

cssの:has()疑似クラスの使い方

2023年12月、cssの:has()疑似クラスがすべてのブラウザでサポートされました。
:has()の使い方を改めて確認してみようと思います。

:has()とは

CSSの :has() とは、特定の子要素や子孫要素を持つ要素を選択するために使用されます。
これは「親要素が特定の条件を満たす子要素を持っている場合に、その親要素をスタイルする」ということです。
別の言い方をすると、「もし中に〇〇がある場合…」という条件を表します。

まずは基本的な使い方

下記の例は.contentsの子要素に「.contents-img」がある場合のみスタイルを適用することができます。
この例であれば、画像があれば背景をグレーにします。コンテンツ1は画像があるので背景はグレーになり、コンテンツ2は画像がないので変化はありません。

.contents:has(.contents-img) {
  background-color: #ddd;
}

See the Pen has_01 by naoto saito (@code_ns) on CodePen.

下記のように「.contents-img」のクラス名ではなくimgタグがある場合の時という指定もできます。

.contents:has(img) {
  background-color: #ddd;
}

See the Pen has_02 by naoto saito (@code_ns) on CodePen.

:hoverや:focusなどと組み合わせる

中の要素がhoverした時やinputにfocusした時にのみスタイルを適用することができます。
下記はボタンにhoverした時、inputにfocusした時のみ「.contents」のスタイルが変わります。

.contents:has( button:hover ) {
  box-shadow: 0px 2px 47px -14px #777777;
}

.contents:has( input:focus ) {
  outline: 2px solid #00f;
}

See the Pen has_04 by naoto saito (@code_ns) on CodePen.

:notとの組み合わせ

否定擬似クラスの「:not()」と組み合わせることができます。
下記の例は、画像がない場合背景がグレーになります。

.contents:not(:has(.contents-img)) {
  background-color: #ddd;
}

See the Pen has_01 by naoto saito (@code_ns) on CodePen.

直下セレクタとの組み合わせ

下記のように直下セレクタと組み合わせることができます。

.contents:has( > .contents-text ) {
  background-color: #ddd;
}

See the Pen has_06 by naoto saito (@code_ns) on CodePen.

独自データ属性との組み合わせ

下記のように独自データ属性と組み合わせることができます。

.contents:has( .contents-title[data-a="hoge"] ) {
  background-color: #ddd;
}

See the Pen has_06 by naoto saito (@code_ns) on CodePen.

いかがでしょうか?
cssの:has()疑似クラスの使い方を確認しました。意外と柔軟に色々なことと組み合わせができますね!
今までjsを使わないと選択できなかった親要素が、今回のhas()を使うことで対応できるので今後どんどん利用しようと思います。

[Solr] Circuit Breaker の新機能

Solr 9.4 で Circuit Breaker にいろいろと変更が加えられました。以前の記事で取り上げたときとは変わったところも多いです。

  • CPUCircuitBreakerが名前の通りCPU使用率をチェックするようになりました。以前はCPUと言いつつ実際にはロードアベレージをチェックしていました
  • ロードアベレージをチェックする Circuit Breaker は LoadAverageCircuitBreaker になりました
  • 検索リクエストだけでなく更新リクエストにも効くようになりました

これらの変更に伴い設定方法が変更になっています。

CPUCircuitBreaker

クラス名と閾値を指定します。たとえば以下のように指定すると、CPU使用率75%を超えたら発動します。

<circuitBreaker class="org.apache.solr.util.circuitbreaker.CPUCircuitBreaker">
 <double  name="threshold">75</double>
</circuitBreake>

LoadAverageCircuitBreaker

クラス名と閾値を指定します。たとえば以下のように指定すると、ロードアベレージ8.0を超えたら発動します。

<circuitBreaker class="org.apache.solr.util.circuitbreaker.LoadAverageCircuitBreaker">
 <double  name="threshold">8.0</double>
</circuitBreaker>

MemoryCircuitBreaker

クラス名と閾値を指定します。たとえば以下のように指定するとメモリ使用率75%を超えたら発動します。

<circuitBreaker class="org.apache.solr.util.circuitbreaker.MemoryCircuitBreaker">
 <double name="threshold">75</double>
</circuitBreaker>

リクエストタイプの指定

リクエストタイプとして search, update を指定できます。上記の例のようにリクエストタイプをしない場合はデフォルトとして search が指定されたことになります。search, update それぞれに別の閾値を設定することもできます。

以下の例の場合、CPU使用率が80%を超えたら更新リクエストの受付を停止し、95%を超えたら検索リクエストを停止するという設定になります。

<config>
  <circuitBreaker class="solr.CPUCircuitBreaker">
   <double  name="threshold">80</double>
   <arr name="requestTypes">
     <str>update</str>
   </arr>
  </circuitBreaker>

  <circuitBreaker class="solr.CPUCircuitBreaker">
   <double  name="threshold">95</double>
   <arr name="requestTypes">
     <str>query</str>
   </arr>
  </circuitBreaker>
</config>

WebAssemblyを使ってブラウザでRubyを動かす

WebAssemblyによりJavaScript以外のプログラミング言語で書かれたコードをブラウザ上で動かす道が広く開かれました。現時点ではRustが使われることが多いようですが、RubyやPythonなどのスクリプト言語を利用する手段も整ってきています。たとえばRubyはバージョン3.2からWebAssembly上で動くようになりました。
WebAssembly 上で動くようにコンパイルされたRubyインタープリターがruby.wasmで、そのruby.wasm 上でRubyのコードが動きます。

ブラウザ上でRubyを動かすのは非常に簡単です。以下はruby.wasmのサイトのQuick Exampleです。

<html>
  <script src="https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@2.1.0/dist/browser.script.iife.js"></script>
  <script type="text/ruby">
    puts "Hello, world!"
  </script>
</html>

これをexample.htmlとして保存し、同じディレクトリでRubyのhttpdを起動します。

ruby -run -e httpd .

ブラウザで以下にアクセスします。

http://localhost:8080/example.html

注意しないといけないのは、puts の実行結果がそのままブラウザ上で表示されるわけではないことです。デベロッパーツールを開いてコンソールを見ると”Hello, world!”が出力されていることがわかります。

ブラウザ上に表示するためにはDOMを操作する必要があります。RubyからはJSパッケージを使ってJavaScriptを通じてDOMを操作できます。

<html>
  <script src="https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@2.1.0/dist/browser.script.iife.js"></script>
  <script type="text/ruby">
    require "js"
    document = JS.global[:document]
    body = document[:body]
    button = document.getElementById("b1")
    button.addEventListener("click") do |e|
      div = document.getElementById("d1")
      div[:innerText] = "Hello, World""
    end
  </script>

  <button id="b1">Say Hello</button>
  <div id="d1"></div>
</html>

ボタンを押すとその下に”Hello, World!”と出力されます。

Slackのブックマークと後で読む機能が便利です

仕事でSlackを使っているのですが流れてくるメッセージが多くてメンション付きのものだったり後で読もうとしたものだったりを忘れることはありませんか?
そんな時に便利なのがブックマークする、後で読むの機能です。

基本的には作業の記録などはプロジェクト管理ツールのチケット管理でやっていますがチケットに記載するほどのことではないやりとりやTODOとして保持していたり返信待ちに使ったりと後で忘れないようにするのに便利です。

使い方は簡単で対象のメッセージのメニューから「ブックマークする」を押すだけで後で読むに追加されます。後は画像にある「後で」を押すことでブックマークしたものが一覧で表示されます。読んだ後や対応した後は「完了にする」または「後で」から外すで外せば綺麗に無くなります。

注意点として課金していない場合は長期間経つとブックマークしたメッセージ自体が消えてしまったりするのでそういった場合は別途自分宛に記載しなおしたりメモに残したりが必要です。

メールでも受信トレイを同じような扱いで運用しています。
読み逃しや返信忘れ、予定など現状の対応が必要なものを残したままにしているので作業忘れは少ないです。
ただ迷惑メールや作業メールなどに埋もれると困るので随時フィルターを駆使してやっているので少し手間はかかります。

仕事の進め方、ツールの使い方は人それぞれだと思いますがそれなりに長くこのやり方で運用していますが忘れてしまうことがかなり減っているのでおすすめです。

仕事でSlackを使っているのですが流れてくるメッセージが多くてメンション付きのものだったり後で読もうとしたものだったりを忘れることはありませんか?
そんな時に便利なのがブックマークする、後で読むの機能です。

基本的には作業の記録などはプロジェクト管理ツールのチケット管理でやっていますがチケットに記載するほどのことではないやりとりやTODOとして保持していたり返信待ちに使ったりと後で忘れないようにするのに便利です。

使い方は簡単で対象のメッセージのメニューから「ブックマークする」を押すだけで後で読むに追加されます。後は画像にある「後で」を押すことでブックマークしたものが一覧で表示されます。読んだ後や対応した後は「完了にする」または「後で」から外すで外せば綺麗に無くなります。

注意点として課金していない場合は長期間経つとブックマークしたメッセージ自体が消えてしまったりするのでそういった場合は別途自分宛に記載しなおしたりメモに残したりが必要です。

メールでも受信トレイを同じような扱いで運用しています。
読み逃しや返信忘れ、予定など現状の対応が必要なものを残したままにしているので作業忘れは少ないです。
ただ迷惑メールや作業メールなどに埋もれると困るので随時フィルターを駆使してやっているので少し手間はかかります。

仕事の進め方、ツールの使い方は人それぞれだと思いますがそれなりに長くこのやり方で運用していますが忘れてしまうことがかなり減っているのでおすすめです。