Tao.Sdl Audio вылет в Windows - PullRequest
       30

Tao.Sdl Audio вылет в Windows

0 голосов
/ 18 февраля 2012

У меня есть небольшой кусочек кода для воспроизведения тонов через Tao.Sdl.Он отлично работает на Linux и Mac (с использованием Mono), но происходит сбой на Windows7, 64-разрядная с Mono или .NET.Вот код:

using System;
using System.Runtime.InteropServices;
using Tao.Sdl;

namespace ConsoleApplication1
{
    class Program
    {
        delegate void AudioSpecCallbackDelegate(IntPtr userData, IntPtr stream, int length);
        static Sdl.SDL_AudioSpec desired;
        static IntPtr specPtr;
        static IntPtr obtained;

        static void Main(string[] args)
        {
            Sdl.SDL_Init(Sdl.SDL_INIT_AUDIO);
            desired = new Sdl.SDL_AudioSpec();
            desired.freq = 22050; 
            desired.format = (short)Sdl.AUDIO_S16LSB;
            desired.channels = 1;
            desired.samples = (short)1000; //(short)2205; 
            desired.callback = Marshal.GetFunctionPointerForDelegate((AudioSpecCallbackDelegate)DoCallback);
            desired.userdata = null;
            specPtr = Marshal.AllocHGlobal(Marshal.SizeOf(desired));
            Marshal.StructureToPtr(desired, specPtr, false);
            obtained = IntPtr.Zero;
            if (Sdl.SDL_OpenAudio((IntPtr)specPtr, (IntPtr)obtained) < 0)
            {
                Console.WriteLine("Error opening sdl_audio (1)");
                Console.WriteLine(Sdl.SDL_GetError());
            }
            Sdl.SDL_PauseAudio(0);
            Sdl.SDL_Delay(1000);
            Sdl.SDL_PauseAudio(1);
        }

        public static void DoCallback(IntPtr userData, IntPtr stream, int len)
        {
            Console.WriteLine("{0}, ", len);
            byte[] buffer = new byte[len];
            for (int i = 0; i < len; i++)
                buffer[i] = 0;
            Marshal.Copy(buffer, 0, stream, len);
        }
    }
}

Сбой в Windows при второй попытке обратного вызова.Вы видите что-то, что я делаю явно неправильно?Возможно, у меня нет правильных значений для freq, или, возможно, формат имеет значение для Windows?

В качестве альтернативы, я не могу понять, как отлаживать низкоуровневый код ... он просто падает в VisualСтудия или в MonoDevelop.Или, если у вас есть предложения по повторному выполнению этого кода с использованием другой системы.Цель: уметь обрабатывать байты, которые будут воспроизводиться через звуковую систему в C # на Mac, Windows и Linux.

1 Ответ

1 голос
/ 20 февраля 2012

Я закончил тем, что переписал код в SdlDotNet, хотя там есть еще одна ошибка, для которой требуется окноЯ просто создаю небольшое окно и закрываю его после открытия потока.Следующее работает на Linux и Windows7.Нужно проверить на Mac.Я никогда не обнаруживал, что это за ошибка ... возможно, это связано с необходимостью окна.У следующего также есть фактический код для создания тона.Я видел несколько довольно ошибочных примеров в SDL, чтобы сделать это.

public class AudioManager : IDisposable {
    const int playbackFreq = 44100;
    const int samples = 2048;
    const double pi2 = 360 * Math.PI / 180.0;
    private bool disposed = false;
    private bool initialized = false;
    SdlDotNet.Audio.AudioStream stream;
    byte[] buffer8;

    double time = 0;
    double volume;
    double frequency1 = -1;
    double frequency2 = -1;
    SdlDotNet.Audio.AudioCallback audioCallback = new SdlDotNet.Audio.AudioCallback(Callback)

    public AudioManager()
    {
        stream = new SdlDotNet.Audio.AudioStream(playbackFreq, 
                             SdlDotNet.Audio.AudioFormat.Unsigned8, 
                             SdlDotNet.Audio.SoundChannel.Mono, 
                             samples, 
                             audioCallback, 
                             null);
        buffer8 = new byte[samples];
        volume = 1.0;

        // BUG: OpenAudio (or lower) apparently requires a visible screen for some reason:
        SdlDotNet.Graphics.Video.SetVideoMode(1, 1);
        SdlDotNet.Audio.Mixer.OpenAudio(stream);
        // BUG: close (or hide) it
        SdlDotNet.Graphics.Video.Close();
    }

    public void beep(double duration, double freq) {
        frequency1 = freq;
        frequency2 = -1;
        Tao.Sdl.Sdl.SDL_PauseAudio(0);
        Tao.Sdl.Sdl.SDL_Delay((int)(duration * 1000));
        Tao.Sdl.Sdl.SDL_PauseAudio(1);
    }

    void Callback(IntPtr userData, IntPtr stream, int len)
    {
        double slice = 1.0 / playbackFreq * pi2; 
        for (int buf_pos = 0; buf_pos < len; buf_pos++ )
        {
            buffer8[buf_pos] = (byte)(127 + Math.Cos(time) * volume * 127);
            time += frequency1 * slice;
            if (time > pi2)
                time -= pi2;
        }
        Marshal.Copy(buffer8, 0, stream, len);
    }
...