2

こんにちはStackOverflowの達人。これが私の最初の質問なので、すぐに参加できることに興奮しています。

私はiOSアレイをもう少しよく理解しようとしていますが、壁にぶつかりました。FMODを使ったサウンドアプリを作っています。私はすべてが完璧に機能していますが、9つのボタンがあり、それぞれが押すと異なる.wavファイルを再生し、リリースするとそのサウンドを停止することを除いて、ほぼ同じことを実行します。それを配列に入れて、コードを単純化して短縮したいと思います。そこで迷子になります。私はコードを取り除いて、現在何が起こっているかを示しました。何か案は?

.h

@interface {

FMOD::Sound    *sound1;
FMOD::Sound    *sound2;
FMOD::Sound    *sound3;
FMOD::Sound    *sound4;
FMOD::Sound    *sound5;
FMOD::Sound    *sound6;
FMOD::Sound    *sound7;
FMOD::Sound    *sound8;
FMOD::Sound    *sound9;

}

- (IBAction)playSound1:(id)sender;
- (IBAction)stopSound1:(id)sender;
- (IBAction)playSound2:(id)sender;
- (IBAction)stopSound2:(id)sender;
- (IBAction)playSound3:(id)sender;
- (IBAction)stopSound3:(id)sender;
- (IBAction)playSound4:(id)sender;
- (IBAction)stopSound4:(id)sender;
- (IBAction)playSound5:(id)sender;
- (IBAction)stopSound5:(id)sender;
- (IBAction)playSound6:(id)sender;
- (IBAction)stopSound6:(id)sender;
- (IBAction)playSound7:(id)sender;
- (IBAction)stopSound7:(id)sender;
- (IBAction)playSound8:(id)sender;
- (IBAction)stopSound8:(id)sender;
- (IBAction)playSound9:(id)sender;
- (IBAction)stopSound9:(id)sender;

m。

- (void)viewWillAppear:(BOOL)animated {

[[NSString stringWithFormat:@"%@/sound1.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound1);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound2.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound2);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound3.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound3);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound4.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE, NULL, &sound4);
    ERRCHECK(result);
    result = sound4->setMode(FMOD_LOOP_NORMAL);
    ERRCHECK(result);

    [[NSString stringWithFormat:@"%@/sound5.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound5);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound6.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound6);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound7.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound7);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound8.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound8);
    ERRCHECK(result);


    [[NSString stringWithFormat:@"%@/sound9.wav", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
    result = system->createSound(buffer, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound9);
    ERRCHECK(result);

}



- (IBAction)playSound1:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = system->playSound(FMOD_CHANNEL_FREE, sound1, false, &wob01);
    ERRCHECK(result);    
}

- (IBAction)stopSound1:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = wob01->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound2:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = system->playSound(FMOD_CHANNEL_FREE, sound2, false, &wob02);
    ERRCHECK(result);    
}

- (IBAction)stopSound2:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = wob02->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound3:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = system->playSound(FMOD_CHANNEL_FREE, sound3, false, &wob03);
    ERRCHECK(result);    
}

- (IBAction)stopSound3:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = wob03->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound4:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = system->playSound(FMOD_CHANNEL_FREE, sound4, false, &wob04);
    ERRCHECK(result);    
}

- (IBAction)stopSound4:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = wob04->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound5:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = system->playSound(FMOD_CHANNEL_FREE, sound5, false, &wob05);
    ERRCHECK(result);    
}

- (IBAction)stopSound5:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = wob05->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound6:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = system->playSound(FMOD_CHANNEL_FREE, sound6, false, &wob06);
    ERRCHECK(result);    
}

- (IBAction)stopSound6:(id)sender
{
    FMOD_RESULT result = FMOD_OK;

    result = wob06->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound7:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = system->playSound(FMOD_CHANNEL_FREE, sound7, false, &wob07);
    ERRCHECK(result);    
}

- (IBAction)stopSound7:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = wob07->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound8:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = system->playSound(FMOD_CHANNEL_FREE, sound8, false, &wob08);
    ERRCHECK(result);    
}

- (IBAction)stopSound8:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = wob08->stop();
    ERRCHECK(result);   
}

- (IBAction)playSound9:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = system->playSound(FMOD_CHANNEL_FREE, sound9, false, &wob09);
    ERRCHECK(result);    
}

- (IBAction)stopSound9:(id)sender
{
    FMOD_RESULT result = FMOD_OK;
    result = wob09->stop();
    ERRCHECK(result);   
}

ご覧のとおり、すべてのコードが繰り返されています。これが私がそれを機能させることができた唯一の方法ですが、これらを配列に入れることができることを私は知っています、私はそれを理解することができません。おそらくNSMutableArrayと「sound1」、「sound2」などをリストアップしてから、インターフェイスビルダーで各ボタンにタグを割り当てますか?理想的には、stopSound用に1つ、playSound用に1つ、タグを使用して正しいサウンドファイルを再生または停止する関数が必要です。FMODのsystem->createSound()を使用する場合、最後の引数は新しく作成されたサウンドを格納する変数です。代わりに配列または辞書に格納する方法はありますか?もしそうなら、私はそれを理解することはできません。

どんなアドバイスでもありがたいです。この単純な問題に対して頭を殴るのはやめたいと思います。

ありがとうございました!

4

3 に答える 3

8

サウンドを のサブクラスにラップしNSObjectて、自己完結型のユニットにします。サウンドには、、、、などの操作とplay、などのアクセサがあります。stoppauseisPlaying

次に、さらに汎用的にするために、パターン"*.wav"に一致するすべてのファイルを検索し、一致したファイル名ごとに、Soundそのファイル名でオブジェクトを初期化し、配列に追加します。

Sound オブジェクトは次のようになります。

@interface Sound : NSObject

@property FMOD::Sound *sound;

- (id)initWithSoundFilePath:(NSString *)path;
- (void)play;
- (void)stop;

@end

@implementation Sound

- (void)dealloc {
    // free the memory occupied by the sound pointer here
}

- (id)initWithSoundFilePath:(NSString *)path {
    self = [super init];
    if (self) {
        result = system->createSound(path, FMOD_SOFTWARE | FMOD_LOOP_NORMAL, NULL, &sound);
        ERRCHECK(result);
    }
    return self;
}

- (void)play {
    FMOD_RESULT result = FMOD_OK;
    result = system->playSound(FMOD_CHANNEL_FREE, sound, false, /* What is this wob? */);
    ERRCHECK(result);
}

- (void)stop {
    FMOD_RESULT result = FMOD_OK;
    result = /* What is this wob */->stop();
    ERRCHECK(result);   
}

@end

それで、あなたはそれを持っています。サウンドがうまくカプセル化されました。この回答は、特定のディレクトリ内のいくつかの基準に一致するすべてのファイルのリストを見つけるのに役立つことがわかりました。ビュー コントローラーでそれを使用して、関連するすべてのサウンド オブジェクトを自動的に生成し、それを配列に追加することができます。

- (NSArray *)getPathsOfSoundFiles {
    NSString *rootPath = [[NSBundle mainBundle] resourcePath];
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray *files = [fm contentsOfDirectoryAtPath:rootPath error:nil];
    NSPredicate *soundFileFilter = [NSPredicate predicateWithFormat:@"self ENDSWITH '.wav'"];
    NSArray *soundFilePaths = [files filteredArrayUsingPredicate:soundFileFilter];
    return soundFilePaths;
}

すべての .wav ファイルへのパスを取得できるようになったので、次のステップは、自分のviewWillAppear方法または最も理にかなった方法でそれらを初期化することです。

- (void)viewWillAppear:(BOOL)animated {
    NSArray *paths = [self getPathsOfSoundFiles];
    NSMutableArray *sounds = [NSMutableArray array];
    for (NSString *path in paths) {
        Sound *sound = [[Sound alloc] initWithSoundFilePath:path];
        [sounds addObject:sound];
    }
    self.sounds = sounds;
}

また、sounds 配列のセットアップを使用すると、特定のサウンドの再生と停止がかなり簡単になります。Use を使用して、インデックスを配列に取り込んだり、Soundオブジェクト自体を取得してジョブを実行したりするメソッドを作成できます。

- (void)playSoundAtIndex:(NSUInteger)soundIndex {
    Sound *sound = [self.sounds objectAtIndex:soundIndex];
    [sound play];
}

- (void)stopSoundAtIndex:(NSUInteger)soundIndex {
    Sound *sound = [self.sounds objectAtIndex:soundIndex];
    [sound stop];
}
于 2012-09-08T21:41:33.107 に答える
1

コードを大幅に一般化できます。

  • 配列を使用してサウンドと「ウォブ」を保存する
  • のようなものでループを使用する[NSString stringWithFormat:@"%@/sound%i.wav", [[NSBundle mainBundle] resourcePath], index]
  • タグ(Interface Builder で設定するか、View Controller のコードでボタンを作成するときに自動化できます) を使用して、再生するサウンドまたは停止するウォブを決定するアクションが1-playSound:つだけあります。-stopStound:sender
于 2012-09-08T21:43:45.693 に答える
-3

UIButton をサブクラス化し、タッチ メソッドをオーバーライドして、これらのアクションが発生したときにオーディオ ファイルを再生することを強くお勧めします。UIButton をサブクラス化するときは、ヘッダー ファイルにプロパティを設定して、オーディオ ファイルまたはオーディオ ファイルの場所の文字列を渡して、簡単に動的にすることができます。

次に、前述のようにメイン ファイルで、これらのタッチ メソッド (touchesBegan、touchesEnded など) をオーバーライドして、ヘッダー ファイルで定義したカスタム プロパティを再生します。

それが私が少なくともあなたの問題に取り組む方法です。そうすれば、渡すオーディオファイルに応じてまったく同じことを実行できる UIButton サブクラスが1つだけになります。

于 2012-09-08T20:34:27.593 に答える