STRAIGHTパラメタを保存するファイルのことを、STF(STraight Format)ファイルと呼びます。 ここでは、このSTFファイルを読み書きするためのAPIについて説明します。 なお、現在はファイルのみのサポートとなりますが、将来的にはストリーミングなども サポートする予定です。
STFの構造は以下のようになっています。 [〜]で囲まれているのは省略可であることを示します。
'STRT' <16bit 0xfeff (エンディアン判定のため)> <32bit ヘッダサイズ in byte(次のチャンクまでの大きさ)> <16bit ファイル形式(バージョン)ID> <16bit チャネル数(原則1)> <32bit サンプリング周波数> ['CHKL' <32bit チャンクサイズ in byte> <4文字のチャンクが並んでいる>] ['NXFL' <32bit チャンクサイズ in byte> <相対パスファイル名文字列 NUL文字なし>] 'F0 ' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit 1> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <F0のデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >] ['UVF0' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit 1> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <非有声音部分のF0のデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >]] ['PRLV' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit 1> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <周期性レベルのデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >]] ['F0CN' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit 候補数> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <F0候補パラメータのデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >]] 'AP ' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit FFTポイント> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <非周期性指標のデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >] ['APSG' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit 2> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <非周期性指標に対するシグモイド関数のパラメータのデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >]] 'SPEC' <32bit チャンクサイズ in byte> <64bit double シフト長> <32bit フレーム数> <32bit FFTポイント> <16bit ビット/サンプル(33=float)> <64bit double 重み係数,default=1.0> <32bit データサイズ> <スペクトログラムのデータ> [<シフト長が0の場合、64bit doubleの時間情報がフレーム数分 >]
読み込みの際は、チャンクのIDに応じて処理を変える必要があります。 一方、書き込みの際は、所望のチャンクを単に書き込めば良いだけなので、 読み込みよりも処理は単純になります。
if ((sf = straightFileOpen(inputFileName, "r")) != NULL) { if (straightFileLoadHeader(sf, straight) == ST_TRUE) { char chunkId[5]; long chunkSize; source = straightSourceInitialize(straight, NULL); specgram = straightSpecgramInitialize(straight, NULL); while (straightFileLoadChunkInfo(sf, chunkId, &chunkSize) == ST_TRUE) { if (strcmp(chunkId, "F0 ") == 0) { straightFileLoadF0(sf, source); } else if (strcmp(chunkId, "UVF0") == 0) { straightFileLoadUnvoicedF0(sf, source); } else if (strcmp(chunkId, "PRLV") == 0) { straightFileLoadPeriodicityLevel(sf, source); } else if (strcmp(chunkId, "F0CN") == 0) { straightFileLoadF0Candidates(sf, source); } else if (strcmp(chunkId, "AP ") == 0 || strcmp(chunkId, "APSG") == 0) { straightFileLoadAperiodicity(sf, source); } else if (strcmp(chunkId, "SPEC") == 0) { straightFileLoadSpecgram(sf, specgram); } else { straightFileSkipChunk(sf, chunkSize); } } : : straightSourceDestroy(source); straightSpecgramDestroy(specgram); } straightFileClose(sf); }
source = straightSourceInitialize(straight, NULL); straightSourceCompute(straight, source, NULL, 0); specgram = straightSpecgramInitialize(straight, NULL); straightSpecgramCompute(straight, source, specgram, NULL, 0); if ((sf = straightFileOpen(outputFileName, "w")) != NULL) { fprintf(stderr, "Output file: %s\n", outputFileName); straightFileSetChunkList(sf, "F0 AP SPEC"); straightFileWriteHeader(sf, straight); straightFileWriteF0Chunk(sf, source); straightFileWriteAperiodicityChunk(sf, source); straightFileWriteSpecgramChunk(sf, specgram); straightFileClose(sf); } straightSourceDestroy(source); straightSpecgramDestroy(specgram);
#include <straight/straight.h> typedef struct _StraightFile *StraightFile;
#include <straight/straight.h> StraightFile straightFileOpen(char *filename, char *mode);
#include <straight/straight.h> stBool straightFileClose(StraightFile sf);
#include <straight/straight.h> char *straightFileGetNextFile(StraightFile sf); char *straightFileGetChunkList(StraightFile sf); stBool straightFileGetEndian(StraightFile sf, stBool *bigEndianFlag);
straightFileGetEndianは、ファイルのエンディアン情報を取得します。
これらの関数は、通常、読み込みモードで開いているファイルに対して使用します。 straightFileLoadHeaderを呼び出す前は、正しい情報は取得できません。
#include <straight/straight.h> stBool straightFileSetNextFile(StraightFile sf, char *nextFile); stBool straightFileSetChunkList(StraightFile sf, char *chunkList); stBool straightFileSetEndian(StraightFile sf, stBool bigEndianFlag);
straightFileSetEndianは、ファイルのエンディアン情報を設定します。 この関数を呼び出さない場合は、その環境のネイティブのエンディアンとなります。
これらの関数は、通常、書き込みモードで開いているファイルに対して使用します。 straightFileWriteHeaderを呼び出す前にこれらの関数を呼び出す必要があります。
#include <straight/straight.h> stBool straightFileLoadHeader(StraightFile sf, Straight straight); stBool straightFileLoadChunkInfo(StraightFile sf, char *chunkId, long *chunkSizePtr); stBool straightFileSkipChunk(StraightFile sf, long chunkSize); stBool straightFileLoadF0(StraightFile sf, StraightSource source); stBool straightFileLoadAperiodicity(StraightFile sf, StraightSource source); stBool straightFileLoadSpecgram(StraightFile sf, StraightSpecgram specgram);
straightFileLoadHeaderは、STFファイルのヘッダに情報を読み込みます。 その他の読み込みを行う前に呼び出す必要があります。
straightFileLoadChunkInfoは、次のチャンクのチャンクIDとチャンクサイズを 読み込みます。STRAIGHTパラメタのチャンクの読み込みを行う前に毎回呼び出す必要があります。 なお、実装としては、実際にこの関数を呼び出してからチャンクIDとチャンクサイズを 読み出すようにはなっていません。
straightFileSkipChunkは、straightFileLoadChunkInfoで得られたチャンクID が不明なものであった場合に、そのチャンクを読み飛ばすための関数です。 straightFileLoadChunkInfoで得られたチャンクサイズを第2引数に指定して下さい。
straightFileLoadF0、 straightFileLoadAperiodicity、 straightFileLoadSpecgramは、それぞれ 'F0 'チャンク、'AP 'チャンク、'SPEC'チャンクの内容を読み込みます。 straightFileLoadChunkInfoで得られるチャンクIDに応じて 適切な関数を呼び出す必要があります。このチャンクIDに対応しない 関数が呼び出された場合の動作は不定です。
#include <straight/straight.h> stBool straightFileWriteHeader(StraightFile sf, Straight straight); stBool straightFileWriteF0Chunk(StraightFile sf, StraightSource source); stBool straightFileWriteAperiodicityChunk(StraightFile sf, StraightSource source); stBool straightFileWriteSpecgramChunk(StraightFile sf, StraightSpecgram specgram);
straightFileWriteHeaderは、STFファイルのヘッダに情報を書き込みます。 その他の書き込みを行う前に呼び出す必要があります。
straightFileWriteF0Chunk、 straightFileWriteAperiodicityChunk、 straightFileWriteSpecgramChunkは、それぞれ 'F0 'チャンク、'AP 'チャンク、'SPEC'チャンク全体を書き込みます。
Last modified: "2013-04-26 20:01:19 hideki"