[Work/Class/Java with Processing/4_SwingInProcessing]

アート系学生のためのJAVA with Processing - その4-4 JavaのStringクラスを使って文字列処理

Stringクラスの必要性と利便性

ActionCommandや,これからネットワーク越しのメッセージなどを扱う時に,JavaのStringクラスやその類似クラスによる文字列操作は避けて通れない.

が,JavaのStringは他言語の標準ライブラリに比べて異様なまでに便利であり,標準で備えていない機能はないとも言えるぐらいである.ActionCommandやネットワークメッセージに使う基本的な機能のみを紹介し,あとはJavaの公式ドキュメントを紹介する.

Java公式のStringクラスの仕様 https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html

コンストラクタ

String myString = new String("初期化の際の文字列");で最初から「初期化の際の文字列」が入ったStringのインスタンスが生成できる.

同じ文字列かどうかを見る

myString.euqals("比較したい文字列");を実行すると,同じ文字列(同じオブジェクトインスタンスではない)ならばtrueが,そうでないならfalseが返ってくる.これを利用し,if文の中に突っ込むことで,これまでActionCommand等の判定を行ってきた.

文字列同士の連結

String firstString = new String("FirstString");
String secondString = new String("SecondString");

が予め存在する時,以下の方法で文字列連結ができる.

String newString = firstString + secondString;
String newString = firstString.concat(secondString);

が,これはfor文やイテレータなど,配列に入っている文字列をぶん回す際には使えないので,StringBufferクラスやStringBuilderクラスを使って以下の方法がある.

StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(firstString);
stringBuffer.append(secondString);
String newString = stringBuffer.toString();
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(firstString);
stringBuilder.append(secondString);
String newString = stringBuilder.toString();

速度としてはStringBuilderクラスを使う方法が一番早く(プラス演算子の1万倍ぐらい早い),次いでStringBufferクラスを使う方法が早い(プラス演算子の5千倍ぐらい早い)に.プラス演算子やconcatは極端に遅いが,足さなければならないStringのインスタンスが少なく量が決まっている場合にはコードが短くなるという利点がある.

スプリッタ文字を指定した切り分け

String givenCommand = "OSC/Desafinado/Toalka/Pikka";

という文字列があった場合,「/」を取り除いて各要素を含んだ配列にし,その配列を用いて状態分岐ツリーを作りたい状況が,特にアクションコマンドやネットワークメッセージを利用している場合に多発する.

String[] splittedCommand = givenCommand.split("/", 0)

と書いてやると,この場合は,"OSC", "Desafinado", "Toalka", "Pikka"という文字列(String型)を要素に持つ配列splittedCommandが生成される.分割に使う文字は

2番目の引数は「最大分割数」なのだが,2番目の引数を省略,もしくは0にすることにより全ての要素の分割が行われる.

2番目の引数に「-1」を指定することにより,空白の要素を除くことができる.例えば,

String givenCommand = "OSC,,Desafinado,Talka,,";

という文字列が与えられた時,2番目の引数が0の場合,

givenCommand.split(",", 0);

配列の中身は,"OSC", "", "Desafinado", "Talka", "", ""となり,空白のStringが入ってしまう.そこで-1を第2引数に指定し,

givenCommand.split(",", -1);

とすると,出力の配列の中身は,"OSC", "Desafinado", "Talka"の3要素のみとなる.

文字列から数字型へ変換

数字から文字列への変換は,単に"文字列" + iのように+演算子で既存の文字列につなぎ合わせることで可能である他,

int number = 1356;
String value = new String(number);

のように,Stringのコンストラクタに数字を渡す方法でも可能である.

またIntegerクラスのオブジェクトインスタンスを作り,インスタンス関数toString()を実行することでも,数字の文字列を得られる.

int number = 1356;
Integer myInteger = new Integer(number);
String value = myInteger.toString();

問題は逆で,文字列として受け取った「数字」を演算可能にするために,例えば整数型などに入れる場合である.整数型ならIntegerクラスのstaticメソッドparseInt()を使う.

String commandNumberInString = "1356";
int commandNumberInInteger = Integer.parseInt(commandNumberInString);

と書くと,int型に変換される.

parseInt()staticメソッドであり,クラスのインスタンスを作っていなくても使うことができる.

StringとJTextFieldを使った実例

前項の複数のボタンでテキストフィールドの内容を書き換えるプログラムを,改造し,テキストフィールドに入力された「,」で区切られた2つの数字を足したり引いたりするプログラム.

import processing.awt.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

void setup(){
  size(640, 480);
  Canvas canvas = (Canvas)surface.getNative();
  JLayeredPane layeredPane = (JLayeredPane)canvas.getParent().getParent();
  
  JTextField textField = new JTextField("3,4");
  textField.setBounds(10, 360, 620, 20);

  MyButtonListener myButtonListener = new MyButtonListener();
  myButtonListener.setTextField(textField);

  JButton button1 = new JButton("Add");
  button1.setBounds(10, 390, 100, 20);
  
  JButton button2 = new JButton("Sub");
  button2.setBounds(120, 390, 100, 20);
  
  button1.setActionCommand("add_two_values");
  button1.addActionListener(myButtonListener);
  
  button2.setActionCommand("sub_two_values");
  button2.addActionListener(myButtonListener);
  
  layeredPane.add(textField);
  layeredPane.add(button1);
  layeredPane.add(button2);


  // ボタンリスナーのインナークラス
  // 例によって,インナークラスではなく別ファイルに分離することもできる
  class MyButtonListener implements ActionListener {
      JTextField textField;
  
      void setTextField(JTextField textField){
	  // テキストフィールドを操作するために,変数に実体を登録しておく
	  this.textField = textField;
      }
  
      @Override
      public void actionPerformed(ActionEvent e){
	  String actionCommand = e.getActionCommand();
	  
	  if(actionCommand.equals("add_two_values")){
	      // 足し算ボタンが押された時
	      
	      // JTextFieldクラスのインスタンスが持つgetText関数を使うと
	      // その時点でテキストフィールドに入力されている文字列を
	      // String型のインスタンスとして取り出すことができる
	      String givenString = textField.getText();

	      // 試しに表示してみる
	      System.out.println(givenString);

	      // テキストフィールドに入っていた2つの数字は,間を「,」で区切って入力する
	      // 一つの文字列として入って来ているので,「,」でsplitする
	      String[] givenValues = givenString.split(",", -1);

	      // Integerクラスが持つ静的関数parseInt関数に「数字の文字列」を入れると
	      // int型に変換してくれる
	      int firstValue = Integer.parseInt(givenValues[0]);
	      int secondValue = Integer.parseInt(givenValues[1]);

	      int answer = firstValue + secondValue;
	      // 足したint型の数字を,
	      // Stringクラスの静的関数valueOfに入れるとString型として出力してくれる
	      textField.setText(String.valueOf(answer));
	  }
	  else if(actionCommand.equals("sub_two_values")){
	      // 引き算の場合も,処理は足し算と同じ
	      String givenString = textField.getText();
	      System.out.println(givenString);
	      
	      String[] givenValues = givenString.split(",", -1);
	      int firstValue = Integer.parseInt(givenValues[0]);
	      int secondValue = Integer.parseInt(givenValues[1]);
	      int answer = firstValue - secondValue;
	      textField.setText(String.valueOf(answer));
	  }
      }   
  } //インナークラスここまで
}

[Work/Class/サウンドトラック制作基礎]

サウンドトラック制作基礎

このテキスト目的

映像基礎の授業の中で行われる「サウンドトラック制作基礎」の授業資料です.

コンテンツ

  1. FL Studioのダウンロードとインストール(Windows用)
  2. FL Studioのダウンロードとインストール(Mac用)
  3. Studio One Primeのダウンロードとインストール
  4. FL Studioによるリズムの打ち込みとStudioOneへの取り込み
  5. FL Studioによるメロディの打ち込み
  6. 「コード」「コードネーム」の基本
  7. FL Studioによるハーモニー,ベース,アルペジオの打ち込み
  8. アヴェイラブルノートスケールを用いたメイン旋律とオブリガート
  9. Studio Oneのオートメーション
  10. Studio Oneでマーカをつけてミックスダウン書き出し
  11. 既存のループ素材の使い方 - FL Studioでテンポ情報を加えて切り貼りする

最終課題

個人課題,グループ課題の両方で点数をつける.個人課題は最終授業の「次の日曜日24:00」,グループ課題は「正月明け」に提出.

個人課題 : オリジナル曲の制作と制作メモ

コード進行をどこからか持ってくるか,自分で作るなどして,オリジナル曲を制作する(劇伴を想定しなくても良い).効果音やループの「フリー素材」ならば使用可能.個人課題のミックスダウンをグループ課題にそのまま用いても良いとする.

制作メモには,「学修番号・名前」「コード進行」,コード進行を他から持って来た場合「オリジナルの曲の名前・作曲者」,フリー素材を用いた場合「フリー素材の出所」を,それぞれ記述すること.

StudioOneのプロジェクトフォルダと使用したサウンドファイル(FL Studioから書き出したものやフリー素材),制作メモを「サウンドトラック制作基礎_最終個人課題_学修番号_名前」という一つのフォルダにまとめた上で,zipファイルに圧縮する.(zipファイル名がサウンドトラック制作基礎_最終個人課題_学修番号_名前.zip」になる) zipファイルをGoogle Driveにアップロードし,共有をかける.

グループ課題 : サウンドトラックの制作とレポート

サウンドトラックの制作

複数のシーンがあり,シーンが移り変わりがある映像を想定して,複数の曲を繋げて構成したStudio Oneプロジェクトによるサウンドトラックを制作する.

グループ課題は明確に「劇伴」であること.つまり「劇伴として必然性がある」ならばドラムだけの曲や,逆にリズム隊が全く含まれていない曲もあって良い.

個々のシーンの曲は,グループ構成員の個人課題のミックスダウンwavファイルを取りまとめたプロジェクトでも良い.その場合事前に相談し,シーンにあった個人課題にすること.効果音やループ素材などもフリー素材ならば取り込んで良い.

レポート

(1)どのような映像を想定し,
(2)どのような心理的効果を視聴者に与えることを目的として,
(3)どのような技法を使って,
制作したかを明確に記述したレポートを作成.

レポート内部に,班名と構成員の学修番号,名前を明記すること.フリー素材を用いた場合にはその出所も書くこと.

Studio Oneのプロジェクトフォルダをzip圧縮したもの,使用したサウンドファイル(複数の曲のミックスダウンをまとめた場合,個々の曲のミックスダウン),全体をミックスダウンしたwavファイル,レポートを一つのフォルダにまとめ,「サウンドトラック制作基礎_最終グループ課題_班名」というフォルダ名にして,zip圧縮して,Google Driveにアップロードし共有をかける.

旧コンテンツ

2016年度授業まで,Studio Oneの代わりに使用していたAcidXpressとAcidProのコンテンツ.Windows環境で映像作品用5.1chサラウンドのサウンドトラックを制作するソフトウェアの中ではAcid Proが一番安価なので,映像制作の参考に残しておく.

  1. Acid Xpressのダウンロードとインストール
  2. Acid XpressのSplitとEdit
  3. Acid Xpressへのサウンドファイル・ループファイルの取り込みとプロジェクトの保存
  4. Acidでのオートメーションの作成
  5. Acid Proでの5.1chサラウンドパンニング

[Work/Class/サウンドトラック制作基礎/composite_piece]

既成のループ素材の使い方 - FL Studioでテンポ情報を加えて切り貼りする

有償ループ素材とフリーのループ素材

これまでは自分で「フレーズの素材」を作ってきた.これを「ループ素材」という呼び方をする.

当然ながら,既に誰かが作ったループ素材というものがあり,これは著作権処理が問題ないようにした上で販売されていたり,フリーで配布されていたりする.特に有償のものは非常にクオリティが高いので,劇伴を作る際には,この既製品の「ループ素材」を最大限活用するとよい.

有償のものはダウンロード販売だったりDVD-ROM販売だったりするが,大体の場合はテンポ情報が書き込まれたサウンドファイルになっていることが多い.
Wavの場合「ACIDized wav」(FL Studioで書き出しているのもこれである), aiffの場合「Apple Loop」という形式であることが多い.

それに対してフリーのものは,テンポ情報が書き込まれていない状態で配布されているものがほとんどである.wavだったりmp3で配布されている.この場合,そのままStudio Oneに突っ込むとテンポを変えても追従してくれない.これは劇伴作成用としては致命的であるので,FL Studioを使ってテンポ情報を書き込む.

テンポを付与して一度書き出す

今回は「ドラム・ループ素材工房」で配布されている素材を使う.

BPM(Beat per minite, テンポのこと)180の素材とBPM120の素材をダウンロードした.大体の場合このようにダウンロードしたファイル名にテンポが書いてあるが,書いていない場合もあるので,ダウンロードする前に配布サイト側のテンポ表示をよく確認すること.

FL Studioを起動し,テンポ表示の部分を上下にドラッグして(左側をドラッグすると大きく変わり,右側をドラッグすると小数点以下が変わる),

テンポを合わせる.今回はテンポBPM180のファイルを使うため,180に合わせた.

ファイルをそのままFinderやExplorerからドラッグ&ドロップする.

するとちゃんとテンポがあった状態で取り込まれる.(ドラムループだとちゃんとテンポにあっていることが,見た目からもわかる)

位置を頭に持って来て1小節目から再生できるようにする.

この状態で,ループを作成した時のようにWavファイルで「Tempo Information」を入れたままWavファイルのExport出力すれば,その後はそのファイルはテンポ情報を持っていることになるので,テンポ変化に追従できるようになる.

注意点

あまりテンポが違いすぎる既成ループ素材を使うと,奇妙に聴こえてしまう.これは「ゆっくりとしたテンポのフレーズ」「速いテンポのフレーズ」で,そもそも全く違ったフレーズであったり,全く違った演奏の仕方をしていたりするからである.

また音響的にもクオリティが低くなってしまうことがある.(場合によっては再生できなくなることもある)

既成ループ素材を使うときには,テンポが近いフレーズを探すこと.

再度読み込んで切り貼りする

「前半だけ欲しい」「後半だけ欲しい」「中間だけ欲しい」などの場合は,要らないところを切ってしまう.

例では8小節のうち前半4小節を切って,後半4小節を2回繰り返すようにしてみる.

テンポをつけてExportしたループを,再度FL Studioに読み込んだ状態.

今までプレイリスト(ソング)操作の中では意識していなかったが,実は「鉛筆」ツールが選択されている.

カッターナイフツールを選択.

今回は5小節目の頭で分割したいので,5小節頭の位置で,カッターナイフで切るように上から下へドラッグする.

分割された.

鉛筆ツールに戻して,前4小節分を右クリックで消す.

残った4小節を前に動かす.

そうすると,パターンとして「残っている」のは,後半4小節だけになるので,パターンの所からドラッグ&ドロップしてきて,後ろに貼り付ける.

あとはこの状態で再度エクスポートしてやればよい.


[Work/Class/サウンドトラック制作基礎/basic_edit]

FL Studio Demoによるリズムの打ち込みとStudio Oneへの取り込み

FL Studio Demoによるリズムの打ち込み

16分音符を基本とする「ステップシーケンサ」で打ち込んでいく

down_mini1.jpg

FL Studio Demoを開いて,「File」→「New」した画面.

down_mini1.jpg

ステップシーケンサに1小節分の各楽器の音を適当に入力.
「PAT」(Pattern)が点灯している状態で,スペースキーを押すか,スピーカマークを押すと,1小節分が再生される.

Kick: バスドラム
Clap: シンバル
Hat: ハイハット
Snare: スネアドラム

down_mini1.jpg

右上のツールウィンドウの一番左を選択.

down_mini1.jpg

「Playlist」ウィンドウが表示される.

down_mini1.jpg

左端の「Browser」から「Patterns」を選択すると,今編集した(デフォルト名)Pattern1が表示される.

down_mini1.jpg

今編集した(デフォルト名)Pattern1を選択.

down_mini1.jpg

時間表示の下の欄のパターンリストの左側をクリックすると,パターンのリストと現在選択しているパターンを見ることができる.

down_mini1.jpg

「Playlist」の中で,ハケツールを選択し,このパターンを置きたい場所を左クリックすると,Pattern 1がPlaylist中に配置される.

down_mini1.jpg

同様にもう一度貼付ける.

down_mini1.jpg

パターンリストの右側の「+」をクリックすると,新しいパターンを追加できる.

down_mini1.jpg

Pattern 2と名前をつける.(自分でわかれば名前は何でも良い.ここではPattern2とする)

down_mini1.jpg

Pattern1と同様にPattern2も適当に入力する.

down_mini1.jpg

パターンリストでPattern 2が選択されていることを確認し,Pattern1と同様にPattern2もPlaylistに貼付ける.

down_mini1.jpg

Playlistウィンドウの左上の磁石ツールから,パターンが小節(Bar)に沿うようにして,移動しやすくする.

down_mini1.jpg

繰り返し,好きなようにパターンを配置していく.「PAT」ではなく「SONG」に切り替えると「Playlist再生モード」(Songモード)になるので,スペースキーを叩くかPlaylistウィンドウ上のスピーカマークをクリックすると,配置されたものが連続して再生される.

down_mini1.jpg

トラックを書き出す.「File」→「Export」→「Wave file」

down_mini1.jpg

セーブ画面が出るので,わかりやすい位置に名前をつけて「保存」

export_config

「Save loop markers」,「Save note markers」,「Save tempo information」にチェックが入っている事を確認して,「Start」

(古いバージョンだと「Save ACIDized」にチェックを入れる)

「Project Type」の「Mode」が「Pattern」だと,現在洗濯しているパターン,「Full Song」だとパターンを並べた「Playlist」の方がが出力される.

他のオプションは「Trim PDC Silence」はオン,「Enable Master Effects」をオン,「Enable Insert Efffects」をオン(画像の状態)にしておくと,音が変わることはない.オフにすると音色にかかっているエフェクトが消えたりする.

Studio Oneのトラックへ取り込む

Studio Oneで,メニューの「トラック」→「オーディオトラックを追加(ステレオ)」でトラックを作り,

Studio Oneへ取り込む

ドラッグ&ドロップで,書き出したPatternやSongを取り込み,並べていく.

FL Studioから書き出されるループ素材は,基本的にステレオであるので,Studio Oneの方も「ステレオ」でトラックを作る.


[Work/Class/サウンドトラック制作基礎/composite_piece]

Studio Oneでマーカをつけてミックスダウン書き出し

ミックスダウン

音量とパンニングの調整が終わったら,これをWavファイルとして書き出す.「多くのトラックをステレオ,つまり左右2chに落とし込む」ことから,ミックスダウンと呼ぶ.

Studio OneのWav書き出し時も,FL Studioと同じくテンポ情報を入れることができるので,複数の曲をまとめて劇伴用のStudio Oneプロジェクトの中で曲ごとにテンポを変えても,テンポを追従させることができる.

Studio Oneの「書き出し」は,FL Studioのような「パターンとFull Song」ではなく,「マーカを設定して,どこからどこまでを書き出すか」によって行う.

マーカトラック表示ボタンを押す.

マーカトラックが表示された.曲の頭には「スタート」マーカが既に入っている.

曲の終わりに移動して,マーカの「+」ボタンを押す.

マーカ「#2」が入った.

メニューの「ソング」→「ミックスダウンをエクスポート」

「書き出し範囲を指定」の場所で,「スタート」マーカと,先ほど曲の終わりに作った「#2」マーカの間を書き出すように指定.(マーカの名前も変えられる)

「テンポをオーディオファイルに書き込み」に必ずチェックを入れる.これによりテンポチェンジに追従できるようになるので,Studio Oneから書き出した曲も素材として使うことができるようになる.

この表示が出た場合,音をたくさん重ねたことにより音量オーバーが起きている.この状態だと音が割れてしまうので,重ねた各トラックの音量を少しずつ下げて調整.(音楽制作現場では「マスタートラックにコンプレッサをかける」などの方法が取られる)

ミックスダウンが書き出された.このファイルをさらにStudio Oneに読み込むことができる.(ただし当然ながら,書き出したものはこれ以上いじることができない)