天下之事,必先处之难,而后易之。

SDL适合多窗口播放音频打开方式

在实现OCX播放控件中要求可以多个窗口播放,注意这里的需求不是分屏。

官方例子

参考:SDL_OpenAudioDevice

SDL_AudioSpec want, have;
SDL_AudioDeviceID dev;

SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
want.freq = 48000;
want.format = AUDIO_F32;
want.channels = 2;
want.samples = 4096;
want.callback = MyAudioCallback; /* you wrote this function elsewhere -- see SDL_AudioSpec for details */

dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
if (dev == 0) {
    SDL_Log("Failed to open audio: %s", SDL_GetError());
} else {
    if (have.format != want.format) { /* we let this one thing change. */
        SDL_Log("We didn't get Float32 audio format.");
    }
    SDL_PauseAudioDevice(dev, 0); /* start audio playing. */
    SDL_Delay(5000); /* let the audio callback play some sound for 5 seconds. */
    SDL_CloseAudioDevice(dev);
}

音频播放工具类

    public unsafe class SDLAudio
    {
        // 设备编号索引
        uint devIndex;

        class aa
        {
            public byte[] pcm;
            public int len;
        }
        int lastIndex = 0;

        private List<aa> data = new List<aa>();

        //private List<byte> data = new List<byte>();
        SDL.SDL_AudioCallback Callback;
        public void PlayAudio(IntPtr pcm, int len)
        {
            lock (this)
            {
                byte[] bts = new byte[len];
                Marshal.Copy(pcm, bts, 0, len);
                data.Add(new aa
                {
                    len = len,
                    pcm = bts
                });
            }

            //SDL.SDL_Delay(10);
        }
        void SDL_AudioCallback(IntPtr userdata, IntPtr stream, int len)
        {
            if (data.Count == 0)
            {
                for (int i = 0; i < len; i++)
                {
                    ((byte*)stream)[i] = 0;
                }
                return;
            }
            for (int i = 0; i < len; i++)
            {
                if (data[0].len > i)
                {
                    ((byte*)stream)[i] = data[0].pcm[i];
                }
                else
                    ((byte*)stream)[i] = 0;
            }
            data.RemoveAt(0);


           
        }
        public int SDL_Init()
        {
            Callback = SDL_AudioCallback;


            SDL.SDL_AudioSpec wanted_spec = new SDL.SDL_AudioSpec();
            wanted_spec.freq = 8000;
            wanted_spec.format = SDL.AUDIO_S16;
            wanted_spec.channels = 1;
            wanted_spec.silence = 0;
            wanted_spec.samples = 320;
            wanted_spec.callback = Callback;

            SDL.SDL_AudioSpec out_spec= wanted_spec;

            // 打开当前索引设备: 传入NULL的设备名称会请求最合理的默认值
            devIndex = SDL.SDL_OpenAudioDevice(null, 0, ref wanted_spec, out out_spec, (int)SDL.SDL_AUDIO_ALLOW_FORMAT_CHANGE);
            if (devIndex < 0)
            {
                throw new ApplicationException("Can't open audio device." );
            }
            //Play  
            SDL.SDL_PauseAudioDevice(devIndex, 0);
            return 0;
        }

        /// <summary>
        ///  暂停
        /// </summary>
        public void PauseAudio()
        {
            SDL.SDL_PauseAudioDevice(devIndex,1);// 暂停声音
        }

        /// <summary>
        /// 播放
        /// </summary>
        public void PlayAudio()
        {
            SDL.SDL_PauseAudioDevice(devIndex,0);//播放声音
        }

        /// <summary>
        /// 关闭设备
        /// </summary>
        public void CloseAudioDevice()
        {
            SDL.SDL_CloseAudioDevice(devIndex);// 关闭播放设备
        }
    }


posted @ 2024-09-22 23:16  boonya  阅读(27)  评论(0)    收藏  举报  来源
我有佳人隔窗而居,今有伊人明月之畔。
轻歌柔情冰壶之浣,涓涓清流梦入云端。
美人如娇温雅悠婉,目遇赏阅适而自欣。
百草层叠疏而有致,此情此思怀彼佳人。
念所思之唯心叩之,踽踽彳亍寤寐思之。
行云如风逝而复归,佳人一去莫知可回?
深闺冷瘦独自徘徊,处处明灯影还如只。
推窗见月疑是归人,阑珊灯火托手思忖。
庐居闲客而好品茗,斟茶徐徐漫漫生烟。

我有佳人在水之畔,瓮载渔舟浣纱归还。
明月相照月色还低,浅近芦苇深深如钿。
庐山秋月如美人衣,画堂春阁香气靡靡。
秋意幽笃残粉摇曳,轻轻如诉画中蝴蝶。
泾水潺潺取尔浇园,暮色黄昏如沐佳人。
青丝撩弄长裙翩翩,彩蝶飞舞执子手腕。
香带丝缕缓缓在肩,柔美体肤寸寸爱怜。
如水之殇美玉成欢,我有佳人清新如兰。
伊人在水我在一边,远远相望不可亵玩。