0

私はこれを数時間理解しようとしています。

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

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

そして、構造体のようにそのメンバー変数に値を割り当てようとすると(通常のsdlでは構造体です)、次のようになります。

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

私はここでvalacドキュメントを見つけました: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;
}

どんな助けでも大歓迎です!

私はまだいくつかの問題を抱えているので、別の更新。私はvapiファイルを変更しました、そしてこれは私が今持っているものです:

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

この関数シグネチャを満たすために(試行しますか?)メソッドがあります:

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

そしてそれを次のように割り当てます:

    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;

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

4

2 に答える 2

0

さて、代表者:

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

Cタイプがあります:

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

userdata と stream は書き込み専用であり、これは本当に必要なものではありません。

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

これでuserdataは、使用するためのいくつかのものへのポインターにすぎません。Vala の言葉では、デリゲートのターゲットです。streamは配列ですが、SDL が割り当てたので、配列の長さではありoutません。すべてを一緒に入れて:lenuint8[] 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ます。callback_target_destroy_notifyここで、メモリ リークを避けるために、Vala はデストラクタを...に割り当てようとしますが、そのためのメンバがないため行き詰まります。それでは、バックアップして再試行しましょう。

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

has_targetValaにユーザーデータがないことを伝え、手動で含めます。構造体については:

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

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

于 2011-11-25T22:46:31.577 に答える
0

VAPIのバグだと思います。sdl.vapi で、変更してみてください

[Compact]
public class AudioSpec {

public struct AudioSpec {

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

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

コードを次のようにします。

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 docs に従って正しいコードを生成するようです。動作する場合は、VAPI の変更を Vala bugzilla に送信することを検討してください。

于 2011-11-25T17:44:58.283 に答える