ページ 11

特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月05日(土) 22:49
by テトラ
DXライブラリを使ってゲームを作っております。
特定のディレクトリにあるwavファイルだけを
全て読み込むことをしたいのですがどの様にすればよいのでしょうか?

特定のディレクトリにある拡張子がwavのタイトル名を全て取得したいです。

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 01:34
by Justy
 Windowsなら WinAPIのFindFirstFileと FindNextFileを使うのがいいかと思いますが、
DXライブラリにそれと似たような関数がありますのでそちらを使ってもいいかもしれません。


http://hpcgi2.nifty.com/natupaji/bbs/pa ... ast&no=434
----- ヘッダから抜粋[color=#d0d0ff" face="monospace]
// 指定のファイル又はフォルダの情報を取得し、ファイル検索ハンドルも作成する( 戻り値: -1=エラー -1以外=ファイル検索ハンドル )
extern int FileRead_findFirst( const char *FilePath, FILEINFO *Buffer ) ;
// 条件の合致する次のファイルの情報を取得する( 戻り値: -1=エラー 0=成功 )
extern int FileRead_findNext( int FindHandle, FILEINFO *Buffer ) ;
// ファイル検索ハンドルを閉じる( 戻り値: -1=エラー 0=成功 )
extern int FileRead_findClose( int FindHandle ) ;
[/color]



 WinAAPIを使うならこちら。

FindFirstFile
http://nienie.com/~masapico/api_FindFirstFile.html

FindFirstFile
http://yokohama.cool.ne.jp/chokuto/uraw ... tFile.html
FindNextFile
http://yokohama.cool.ne.jp/chokuto/uraw ... tFile.html
WIN32_FIND_DATA
http://yokohama.cool.ne.jp/chokuto/uraw ... _DATA.html

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 10:08
by テトラ
URLありがとうございます。

URLを見たのですがイマイチわかりません・・・。
DXライブラリなので搭載されている関数を使おうと思っております。
ただ関数の使い方がよくわかりません。

例えば指定されたパスに5個のwavファイルがあるとします。
それを読み込む為にあらかじめサウンド用のハンドル5個以上用意しとかなければいけませんよね?
しかし5個以上あったら5個しか用意していなかったら配列が壊れてしまうかと思います。
soundにそれぞれのハンドルを入れたいです。

// 現在のソース
int Sound[5];

~main関数↓~

FILEINFO lp;
int hFind = FileRead_findFirst( "DATA/SOUND/BGM/DIR" , &lp );
FileRead_findClose(hFind);

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 11:01
by Justy
>しかし5個以上あったら5個しか用意していなかったら配列が壊れてしまうかと思います
 十分大きな配列を用意しておいて、格納した数をカウントしながら溢れそうになったら
処理を打ち切る or エラーにするか、std::vectir<int>のような動的に伸張するコンテナを使えばいいかと。

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 11:33
by テトラ
なるほど・・・。
あらかじめ用意しておくことにします。

又、~ここ~と書いてある所にどんな処理を書けばよいのかがわかりません・・・。
どうか教えては頂けないでしょうか?

FILEINFO lp;
int hFind = FileRead_findFirst( "DATA/SOUND/BGM/DIR" , &lp );
~ここ~
FileRead_findClose(hFind);

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 12:13
by Justy
 今回は wavファイルだけ探しますので、FileRead_findFirstの末尾は "*.wav"とした方がいいでしょう。

 シンプルに書くとこんな感じです(DATA/SOUND/BGM/DIRディレクトリ内にある wavファイルが対象)。

[color=#d0d0ff" face="monospace] FILEINFO fileInfo;
int hFind = FileRead_findFirst("DATA/SOUND/BGM/DIR/*.wav", &fileInfo);
if(hFind != -1)
{
do
{
if(fileInfo.DirFlag)
continue;

int soundHandle = LoadSoundMem(fileInfo.Name);
if(soundHandle != -1)
// ← ここで配列に格納する

} while(FileRead_findNext(hFind, &fileInfo) == 0);

FileRead_findClose(hFind);
}
[/color]

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 13:22
by テトラ
何度も何度も本当にありがとうございます。
本当に助かっております。

Sound.Wave[1] = LoadSoundMem( "DATA/SOUND/BGM/DIR/over2.wav" );
PlaySoundMem( Sound.Wave[1], DX_PLAYTYPE_LOOP );
等と書くと正常になるので音自体は問題が御座いません。

fileInfo.Nameを見てみるとファイル名しか入っていないので
LoadSoundMem(fileInfo.Name)だけだと音が正常に読み込めておりませんでした。
又、ファイル名(パスを含まない)だけをSound.Name[0]等に格納しておきたいです。

下記の様に試してみたのですが駄目でした・・・。
typedef struct{
    int Wave[LOAD_MAX];
    char Name[128][LOAD_MAX];
}SOUND;

static SOUND Sound;

~メイン↓~
    if(hFind != -1){ 
        int cnt = 0;
        do{ 
            if(fileInfo.DirFlag) continue; 
            int soundHandle = LoadSoundMem(fileInfo.Name);
            char name[128];
            strncpy(name, fileInfo.Name, sizeof(fileInfo.Name));

            // ← ここで配列に格納する 
            if(soundHandle != -1){
                Sound.Wave[cnt]    = soundHandle ;
                //ここでエラーが起こる//Sound.Name = strncpy(Sound.Name[cnt], name, sizeof(name));
                cnt++;
            }
            
        } while(FileRead_findNext(hFind, &fileInfo) == 0); 

        FileRead_findClose(hFind); 
    }

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 14:31
by Justy
>fileInfo.Nameを見てみるとファイル名しか入っていないので
 おっと、ごもっともです。
 ディレクトリパスとファイル名を(sprintf等で)結合したものを LoadSoundMemに渡す必要がありますね。

 そうですねぇ、さすがにその SOUNDクラスはちょっとどうかと思います。
 Wave(ハンドル)と Nameの対応が対になっておらず、しかも数も違うというおかしな状態になっています。
 
 最低でも
[color=#d0d0ff" face="monospace]
struct SoundInfo
{
int handle;
char name[MAX_PATH];
};

struct SoundList
{
int size;
SoundInfo list[LOAD_MAX];
};
[/color]
ようにその2つの情報を対にして対応が取りやすいクラスにした方がいいでしょう。

 で、この前提で書くとこんな感じになります。
[color=#d0d0ff" face="monospace]
static SoundList soundList;

~メイン↓~

static const char basePath[/url] = "DATA/SOUND/BGM/DIR/"; // 対象となるディレクトリ
char path[MAX_PATH];

FILEINFO fileInfo;
sprintf(path, "%s%s", basePath, "*.wav"); // 探すパターンをディレクトリ名込みで作成する
int hFind = FileRead_findFirst(path, &fileInfo);
if(hFind == -1) return;

int index = 0;
do
{
if(fileInfo.DirFlag)
continue;

sprintf(path, "%s%s", basePath, fileInfo.Name); // ディレクトリパスとファイル名を結合
int soundHandle = LoadSoundMem(path);
if(soundHandle != -1)
{
SoundInfo &soundInfo = soundList.list[soundList.size];
soundInfo.handle = soundHandle;
strcpy(soundInfo.name, fileInfo.Name); // ファイル名だけをコピー
++soundList.size;
}

} while(FileRead_findNext(hFind, &fileInfo) == 0 && soundList.size < LOAD_MAX); // 次のファイルが無いかリストの空きが無くなったら終了

FileRead_findClose(hFind);
[/color]

Re:特定のディレクトリにあるwavファイルだけを全て読み込む

Posted: 2010年6月06日(日) 15:00
by テトラ
出来ました!!!!
Justy様、本当にありがとうございます。
わざわざサンプルソースまで頂いて本当に感謝しております。
ありがとうございました!!