= OggPlugin をテストするためのディレクトリ。 svn フォルダだけ消す。 find -name '.svn' -exec rm -rf {} \; == example プリミティブだけを使ったテスト vorbis 読み書き + ヘッダ 123 プリミティブだけを使ったテスト speex読み書き + ヘッダ 45 encodeSoundBuffer: を使った読み書き x (vorbis + speex) 67 OggSound を使ったテスト 89 OggSound を使った読み書き == Building OggPluing on Mac (find-file "../README.txt") == todo pending: ??? (AC_PLUGIN_SEARCH_LIBS(ogg_sync_init, vorbis)) を試す。失敗 == eToys の音名 - サウンドの再生 soundNamed:ifAbsent: - サウンドの保存 addLibrarySoundNamed:samples:samplingRate: バイト列とコーデック情報 サウンドクラスでやるか?コーデッククラスでやるか? フォーマット - 22050 : SampledSound - OggVorbisCodec : OggVorbisCodec - GSMCodec 22050 : GSMCodec 保存の仕方は、やはりレコーダ側で行う。 == (find-file "~/src/speex-1.0.5/src/speexenc.c") todo: コーデックと圧縮率が選択できる。 todo: Trim を探す todo: vorbis で後ろが切れる todo: クラス変数で speex の音質を決めてるのを何とかする。 todo: ogg オブジェクトを安全に開放 todo: speex ステレオ指定可能に。 todo: 毎回フラッシュせずに最後だけ行う。 todo: 連続エンコーディング、単独エンコーディングを考慮した eos の入れ方。 == SoundRecoder で OggVorbis がちゃんと動かない問題 原因 - エンコーダに渡される圧縮データにヘッダが含まれない。 -- SoundRecoder では、録音した細切れのデータを逐次エンコードして SequentialSound に保存する。 -- SequentialSound には CompressedSoundData が音声の解凍を試みる。 -- 先頭の CompressedSoundData 以外にはヘッダが含まれないので問題が発生する。 解決法 - OggSound に必要な機能 -- CompressedSoundData にある機能で、SoundRecoder が使う物。 -- 続きのサウンドの場合は最初のデータ - OggSound の動作 -- codec が生成される。 -- compressSound: によって最初の OggSound が生成される。 -- codec は最初の OggSound を記録する。 -- 次の compressSound: によって続きの OggSound が生成される。 -- 続きの OggSound は最初の OggSound を記録する。 - OggSound デコーダの初期化 -- デコードの最初 初期化 -- 二番目以降。ヘッダのデコーダを使用。 soundAdditions によってサウンドを保存している。 サウンドライブラリ - 複数の CompressedSoundData を同じエンコーダで解凍する。 -- CompressedSoundData には、エンコーダの情報は含まれない(クラスのみ) - 一つの音声データだけを使う -- 互換性の問題? - それぞれ独立して短くエンコーディングを行う。 - OggSound を作成 バッファの長さ決定法 標準で 1/2 秒。samplesPerFrame に従って切り下げる。 == API の設計 必要な項目 - channels - rate - quality speex 操作 - パケットからデコーダを作成 SqSpeexDecoder(packet) - デコーダとパケットから音声を作成 SqSpeexDecode(speex, buffer, bytes) 基本操作 - 作成 SqOggOpen(int mode); - 書き込み SqOggWrite(SqOgg * ogg, const char * buffer, size_t bytes); - 読み込みサイズ SqOggReadSize(SqOgg * ogg); - 読み込み SqOggRead(SqOgg * ogg, char * dest, size_t bytes); - 開放 SqOggClose(SqOgg * ogg); mode = SpeexEncode | SpeexDecode | VorbisEncode | VorbisDecode Ogg 操作 - パケット書き込み SqOggPacketWrite(ogg, packet); - パケット書き込みフラッシュ SqOggPacketFlush(ogg); - パケット読み込み SqOggPacketRead(ogg, packet); file:///c:/takashi/src/ogg/doc/index.html = 現状 (2007-02-13) - Vorbis 再生: 音が途切れるが大体 OK - Vorbis 録音: OK - Vorbis ヘッダ読み書き: 未実装 todo: result オブジェクトをループバッファにするか文書化 todo: endian に関する項目を文書化 = ogg speex エンコード todo: ページを書き込む部分の API 作成 todo: ヘッダコメント出力 = ogg speex デコード goal: spx (ogg speex) フォーマットの Squeak での再生録音 goal: Ogg 共通部分の括り出し - コメントは無視 - header 情報からエンコーダ作成 - 再生 == サンプル音源の作成 sound3.spx sox で 16kHz を raw を作成 $ sox `cygpath -w /cygdrive/c/WINDOWS/Media/tada.wav` -r 16000 -c 1 sound3.raw $ speexenc.exe --comment="test=comment" sound3.wav sound3.spx == ogg から speex の音を取り出す。 (find-file "~/src/speex-1.0.5/src/speexdec.c") (browse-url "file:///c:/takashi/src/libvorbis-1.1.2/doc/index.html") (w3m "file:///c:/takashi/src/libvorbis-1.1.2/doc/index.html") データを渡してパケットを取得するまでの処理の流れを纏める。 - データを渡す SqOggSetBuffer() - パケットを取得 get_next_packet() goal: ファイルを読み込みパケットの情報を返すプログラムの作成 ====================================================================== = テスト 親ディレクトリに OggPlugin のソースコード一式がある。このディレクト リで make すると、OggPlugin をテストする為のプログラムがコンパイルされる。 == windows テストビルド $ export PATH=/cygdrive/c/gnutools/bin/:$PATH または以下のコードで環境変数をセット (setenv "PATH" (concat "C:\\gnutools\\bin\\;" (getenv "PATH"))) $ make (compile "export PATH=/cygdrive/c/gnutools/bin/:$PATH; make -k CFLAGS='-g -Wall' -C C:/takashi/doc/olpcsq/ogg_plugin/test") == linux テストビルド (compile "make -k CFLAGS='-g -Wall' -C ~/doc/olpcsq/ogg_plugin/test") == windows での Plugin ビルド $ /bin/cp ../*.[hc] ~/src/3.7.1/win32/plugins/OggPlugin/ $ cd ~/src/3.7.1/win32/ $ make OggPlugin.dll -f Makefile.mingw32 $ /bin/mv release/OggPlugin.dll ~/doc/olpcsq/ $ export PATH=/cygdrive/c/gnutools/bin/:$PATH emacs 内 (shell-command "/bin/cp ../sqOgg.c ../OggPlugin.h C:/takashi/src/3.7.1/win32/plugins/OggPlugin/") (compile "export PATH=/cygdrive/c/gnutools/bin/:$PATH; make OggPlugin.dll -f Makefile.mingw32 CFLAGS='-g -Wall' -C C:/takashi/src/3.7.1/win32") (rename-file "~/src/3.7.1/win32/release/OggPlugin.dll" "~/doc/olpcsq/OggPlugin.dll" 't) == linux での Plugin ビルド === configure (make-directory "~/src/squeak-svn/platforms/unix/plugins/OggPlugin/") (shell-command "cp ../acinclude.m4 ~/src/squeak-svn/platforms/unix/plugins/OggPlugin/") $ cd platforms/unix/bld $ make -C ../config/ # configure スクリプトを作成 $ ../config/configure --prefix=$HOME CFLAGS=-g squeak-svn/platforms/unix/src/plugins.ext に OggPlugin を追加 === コンパイル ogg_plugin の内容を squeak-svn/platforms/Cross/plugins/OggPlugin にコピーする。 $ cd squeak-svn/platforms/unix/bld $ make OggPlugin.la CFLAGS='-g -Wall' $ cp OggPlugin/.libs/OggPlugin ~/doc/olpcsq/ (setenv "LANG" "C") (make-directory "~/src/squeak-svn/platforms/Cross/plugins/OggPlugin/") (shell-command "cp ../sqOgg.c ../OggPlugin.h ~/src/squeak-svn/platforms/Cross/plugins/OggPlugin/") (compile "make -k OggPlugin.la CFLAGS='-g -Wall' -C ~/src/squeak-svn/platforms/unix/bld/") (rename-file "~/src/squeak-svn/platforms/unix/bld/OggPlugin/.libs/OggPlugin" "~/doc/olpcsq/" 't) (shell-command "mv ~/src/squeak-svn/platforms/unix/bld/OggPlugin/.libs/OggPlugin ~/doc/olpcsq/") == テスト $ make test # 全部のテストを実行 以下のサウンドファイルが必要 - sound1.raw : 44100 Hz 2ch - sound2.raw : 11025 Hz 1ch == イメージ内のテスト - Squeak3.8-full.image を元に行う。 - OggVorbisCodec.cs をファイルイン。 - OggVorbisCodec example3 を実行 - SpeexCodec example1 を実行 ====================================================================== == speex サンプルコードを元にしたプラグインの作成 - file:///home/takashi/pub/speex-manual/index.html フォーマット - int length; - char[] data エンコーディングの仕方 void SqSpeexDecode(SqOgg * ogg, char * readbuffer, int size) の仕様 取得したデコード済みデータがあれば SQ_OGG_SUCCESS を返す 取得したデコード済みデータが無ければ SQ_OGG_NEED_MORE を返す - ループ開始 -- OGG_SPEEX_BEGIN: 開始状態 -- 4 バイトバッファ確保 -- OGG_SPEEX_DECODE_HEADER, speexDecodePos= 0 -- length 読み込む -- OGG_SPEEX_DECODE_HEADER, speexDecodePos= ヘッダ現在位置 -- 読み込めなければ break -- length を元にしてバッファ確保 -- OGG_SPEEX_DECODE_BODY, speexDecodePos= 0 -- データを読み込む -- OGG_SPEEX_DECODE_BODY, speexDecodePos= ボディ現在位置 -- 読み込め無ければ break -- デコード -- 最初に戻る - データがあれば SQ_OGG_SUCCESS を返す - データが足りなければ SQ_OGG_NEED_MORE を返す == サンプルデータ 44100 x 2ch $ sox /usr/share/sounds/shutdown1.wav test.raw 44100 x 1ch $ sox /usr/share/sounds/info.wav test.raw 22050 x 1ch $ sox /usr/share/sounds/info.wav -r22050 test.raw $ play -r22050 -c1 -sw -fs test.raw == my_oggdec.c : ogg ファイルをデコードして 16bit (platform endian interleave) データに変換する。 $ make test カレントディレクトリに、test.ogg があると仮定して test.raw を作成する。 $ make play test.raw を play (sox) で演奏する。 == buftest.c : SqOggResult 構造体のテストをする。 テストを簡単にするために ElectricFence のインストールが必要。 シェルから有効にする。 $ export LD_PRELOAD=/usr/lib/libefence.so gdb 内で有効にする。 (gdb) set environment LD_PRELOAD=/usr/lib/libefence.so #ifdef _WIN32 _setmode( _fileno( stdin ), _O_BINARY ); _setmode( _fileno( stdout ), _O_BINARY ); #endif が必要かもしれない == ChangeLog 2007-03-09: macosx 対応 2007-03-06: etoys で作成と保存 2007-02-26: ogg speex 2007-02-15: spx 再生 2007-02-13: Ogg Vorbis & Spees テスト。 2006-12-19: Ogg Vorbis encode 開始。 2006-12-17: Ogg Vorbis decode がちゃんと動く。