Как инициализировать аудио с помощью Vala / SDL - PullRequest
0 голосов
/ 25 ноября 2011

Я пытался выяснить это уже несколько часов.

Чтобы запустить аудио, мне нужно создать объект 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();
                              ^^^^^^^^^^^^^^^^^^^

И если я пытаюсь просто присвоить значения его элементам-членам как struct (этоструктура в обычном 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)

1033 * Во-первых, 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;

Аааа, наконец-то мой прекрасный генератор белого шума готов!

Ответы [ 2 ]

0 голосов
/ 26 ноября 2011

Хорошо, делегат:

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 это просто указатель на некоторые вещи для вашего использования. С точки зрения Валы, это цель делегата. 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. Теперь, чтобы избежать утечки памяти, Вала попытается назначить деструктор для 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;
}

Итак, пользовательские данные будут переданы вашему обратному вызову, но вам нужно будет привести их самостоятельно, и вам придется управлять памятью. Кроме того, когда структуры выходят из области видимости, Вала собирается вызвать функцию уничтожения. Указав пустую строку, он ничего не сделает. Обычно это освобождает память внутри структуры, но нам не нужно беспокоиться здесь.

0 голосов
/ 25 ноября 2011

Я думаю, что это ошибка в 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.Если это работает, рассмотрите возможность отправки изменений VAPI в bugzilla Vala.

...