2011-11-25 4 views
0

私は数時間前にこれを理解しようとしていました。Vala/SDLでオーディオを初期化する方法

オーディオを起動するには、SDL.AudioSpecオブジェクトを作成してSDL.Audio.Openに渡す必要があります。問題は、あるAudioSpecは、プライベートコンストラクタを持つクラスですので、私は1つを作成しようとすると、私が取得:

sdl.vala:18.25-18.43: error: `SDL.AudioSpec' does not have a default constructor 
     AudioSpec audiospec = new SDL.AudioSpec(); 
           ^^^^^^^^^^^^^^^^^^^ 

そして私はちょうど構造体のようなことだメンバーVARSに値を代入しようとした場合(それは中のstructです通常のSDL)私が手:

sdl.vala:20.3-20.25: error: use of possibly unassigned local variable `audiospec' 
     audiospec.freq = 22050; 
     ^^^^^^^^^^^^^^^^^^^^^^^ 

私はここウァラクドキュメントが見つかりました:http://valadoc.org/sdl/SDL.AudioSpec.html をしかし、それはすべてで多くの助けではありません。

問題のあるコードブロックは次のようになります。

// setup the audio configuration 
AudioSpec audiospec; 
AudioSpec specback; 
audiospec.freq = 22050; 
audiospec.format = SDL.AudioFormat.S16LSB; 
audiospec.channels = 2; 
audiospec.samples = 512; 

// try to initialize sound with these values 
if (SDL.Audio.open(audiospec, specback) < 0) 
{ 
    stdout.printf("ERROR! Check audio settings!\n"); 
    return 1; 
} 

任意の助けいただければ幸いです!

もう1つのアップデートは、まだ問題があります。私はVAPIファイルを変更したが、これは私が今持っているものです。

public void callback(out void* userdata, out uchar stream, int len) 
{ 
    stream = 0; 
    userdata = null; 
} 

としてそれを割り当てる:

public delegate void AudioCallback (out void* userdata, out uchar stream, int len); 

[CCode (cname="SDL_AudioSpec")] 
[Compact] 
public struct AudioSpec { 
    public int freq; 
    public AudioFormat format; 
    public uchar channels; 
    public uchar silence; 
    public uint16 samples; 
    public uint16 padding; 
    public uint32 size; 
    public AudioCallback callback; 
    public void* userdata; 
}// AudioSpec 

私は(?試行)は、この関数のシグネチャを満たすための方法があります:

audiospec.callback = gen.callback; 

言うまでもなく、これはまだ、エラーの多くを得る、動作していない:

/home/gukid/vala/soundgen.vala.c: In function ‘sound_gen_main’: 
/home/gukid/vala/soundgen.vala.c:766:12: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’ 
/home/gukid/vala/soundgen.vala.c:766:72: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’ 
/home/gukid/vala/soundgen.vala.c:766:114: error: ‘SDL_AudioSpec’ has no member named ‘callback_target’ 
/home/gukid/vala/soundgen.vala.c:768:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target’ 
/home/gukid/vala/soundgen.vala.c:769:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’ 
/home/gukid/vala/soundgen.vala.c:770:21: warning: assignment from incompatible pointer type [enabled by default] 
/home/gukid/vala/soundgen.vala.c:771:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target’ 
/home/gukid/vala/soundgen.vala.c:772:11: error: ‘SDL_AudioSpec’ has no member named ‘callback_target_destroy_notify’ 
error: cc exited with status 256 

私はもう少し固いところにいます。

3番目の投稿:EUREKA!私には解決策があります! (議論の余地:P)

まず第一には、sdl.vapiは次のようになります。

[CCode (cheader_filename = "SDL.h")] 
public delegate void AudioCallback (void* userdata, uchar* stream, int len); 

[CCode (cname="SDL_AudioSpec", has_type_id=false)] 
public struct AudioSpec { 
    public int freq; 
    public AudioFormat format; 
    public uchar channels; 
    public uchar silence; 
    public uint16 samples; 
    public uint16 padding; 
    public uint32 size; 
    [CCode (delegate_target = false, type = "void*")] 
    public weak AudioCallback callback; 
    public void* userdata; 
}// AudioSpec 

そして私はただの関数を作成することができます

public static void callback(void* userdata, uchar* stream, int len) 

そして:

audiospec.callback = callback; 

ああ、ついに私の美しいホワイトノイズジェネレータが完成しました!

答えて

0

私はVAPIのバグだと思います。 sdlで。

:VAPI、

[CCode (cname="SDL_OpenAudio")] 
public static int open(AudioSpec desired, out AudioSpec obtained); 

public struct AudioSpec { 

[CCode (cname="SDL_OpenAudio")] 
public static int open(AudioSpec desired, AudioSpec obtained); 

[Compact] 
public class AudioSpec { 

を変更してみてください、あなたのコードを作るには、のように見えます

AudioSpec audiospec = AudioSpec(); 
AudioSpec specback; 
audiospec.freq = 22050; 
audiospec.format = SDL.AudioFormat.S16LSB; 
audiospec.channels = 2; 
audiospec.samples = 512; 

// try to initialize sound with these values 
if (SDL.Audio.open(audiospec, out specback) < 0) 
{ 
    stdout.printf("ERROR! Check audio settings!\n"); 
    return 1; 
} 

とテストします。それはSDLのドキュメントに従って正しいコードを生成するようです。それが機能する場合は、Vala bugzillaにVAPIの変更を提出することを検討してください。

+0

コンパイルするにはうまくいきました!私はまだ音を開くことができません、そして、私はコールバックポインタを持たないenumと何か関係があるかもしれないと思っています。元のsdl: typedef struct ... void(*コールバック)(void * userdata、Uint8 * stream、int len); 私はsdl.vapiに追加する方法を見つけることができます。 – ioev

0

さて、デリゲート:

public delegate void AudioCallback (out void* userdata, out uchar stream, int len); 

はCタイプがあります。ユーザデータとストリームが書き込み専用、本当にあなたが望むものではありませんれている

void(*AudioCallback)(void**userdata, unsigned char* stream, int len); 

void (*callback)(void *userdata, Uint8 *stream, int len); 

これでは、userdataは、使用するための単なるポインタです。 Valaの言葉では、それは代表者の目標です。 streamは配列ですが、SDLはそれを割り当てているので、outではなく、lenは配列の長さなので、Valaは自動的にそれをuint8[] streamで処理できます。一緒にすべてを置く:

[CCode(instance_pos = 0)] 
public delegate void AudioCallback(uint8[] stream); 

instance_posは、ユーザデータがあるValaのを伝えます。それは通常それが最後であると仮定します。構造体の通り:

[CCode (cname="SDL_AudioSpec", destroy_function = "")] 
public struct AudioSpec { 
    ... 
    [CCode(delegate_target_cname = "userdata")] 
    public AudioCallback callback; 
} 

これはuserdataにターゲットを保存するコールバックを作成します。今、メモリが漏れるのを防ぐため、Valaはデストラクタをcallback_target_destroy_notifyに割り当てようとしています。それでは、バックアップして、もう一度試してみましょう:

[CCode(has_target = false)] 
public delegate void AudioCallback(void* userdata, uint8[] stream); 

has_targetがそこにはユーザデータがありませんし、我々はそれを手動で含まValaの伝えます。構造体については:だから

[CCode (cname="SDL_AudioSpec", destroy_function = "")] 
public struct AudioSpec { 
    ... 
    public AudioCallback callback; 
    public void* userdata; 
} 

、ユーザデータは、コールバックに渡されますが、あなたはそれを自分でキャストする必要がありますし、あなたがメモリを管理する必要があります。さらに、構造体が範囲外になると、Valaはdestroy関数を呼び出すことになります。空の文字列を指定することで、何もしません。通常、これは構造体内のメモリを解放しますが、ここでは心配する必要はありません。

+0

ありがとうございました!私は実際に少しの研究を行いましたが、解決策を思い付いてコンパイルして私に何か騒音を与えます。おそらくメモリリークや何か(私の解決策)よりも、私は今のところそれについて心配していません。もう一度、あなたのすべての助けをありがとう、決して私自身でこれを考え出したことはありませんでした! – ioev

関連する問題