C# FMOD使用用户创建的流创建声音

C# FMOD使用用户创建的流创建声音,c#,fmod,C#,Fmod,在C#中,给定一个本应播放SNES SPC文件和FMOD的DLL,为什么调用system.createSound失败 var ret = system.init(32, FMOD.INITFLAGS.NORMAL, (IntPtr)null); var soundEx = new FMOD.CREATESOUNDEXINFO() { cbsize = Marshal.SizeOf(soundEx), fileoffset = 0, length = ~0U, nu

在C#中,给定一个本应播放SNES SPC文件和FMOD的DLL,为什么调用
system.createSound
失败

var ret = system.init(32, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
var soundEx = new FMOD.CREATESOUNDEXINFO()
{
    cbsize = Marshal.SizeOf(soundEx),
    fileoffset = 0,
    length = ~0U,
    numchannels = 2,
    defaultfrequency = 32000,
    format = FMOD.SOUND_FORMAT.PCM16,
    pcmreadcallback = pcmreadcallback,
    pcmsetposcallback = pcmsetposcallback,
    dlsname = null,
};
var mode = FMOD.MODE.DEFAULT | FMOD.MODE.OPENUSER
         | FMOD.MODE.LOOP_NORMAL | FMOD.MODE.CREATESTREAM;
ret = system.createSound((string)null, mode, ref soundEx, ref sound);
//^-- ERR_INVALID_PARAM
ret = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel);
将其与FMOD附带的
usercreatedsound
示例进行比较:

FMOD.MODE mode = (FMOD.MODE._2D | FMOD.MODE.DEFAULT
               | FMOD.MODE.OPENUSER | FMOD.MODE.LOOP_NORMAL
               | FMOD.MODE.HARDWARE);
//snip
createsoundexinfo.cbsize            = Marshal.SizeOf(createsoundexinfo);
createsoundexinfo.fileoffset        = 0;
createsoundexinfo.length            = frequency * channels * 2 * 2;
createsoundexinfo.numchannels       = (int)channels;
createsoundexinfo.defaultfrequency  = (int)frequency;
createsoundexinfo.format            = FMOD.SOUND_FORMAT.PCM16;
createsoundexinfo.pcmreadcallback   = pcmreadcallback;
createsoundexinfo.pcmsetposcallback = pcmsetposcallback;
createsoundexinfo.dlsname           = null;
//snop
result = system.createSound(
    (string)null, 
    (mode | FMOD.MODE.CREATESTREAM), 
    ref createsoundexinfo,
    ref sound);
长度,频率。。。没关系


编辑:我已经确认SPC播放器可以工作,至少在初始化过程中是这样,FMOD附带的示例可以正常构建和运行。唯一特别有意义的变化是,除了在尝试运行时旋转设置外,以4.0风格编写。并非所有声卡都可以播放任意采样率。32Khz不是一个“普通”频率,如44.1、48、96等

  • 你试过FMOD.MODE.SOFTWARE吗
  • 您可以使用仲裁采样率,但需要切换到ASIO
你和FMOD有联系吗?如果没有,那么考虑一下,你将比在FMOD做这些事情有更多的控制。

使用BASSMix的示例: 见下文备注

using System;
using Un4seen.Bass;
using Un4seen.Bass.AddOn.Mix;

namespace XXX
{
    public class Resampler : IDisposable
    {
        private readonly int _channels;
        private readonly string _filename;
        private readonly int _samplerate;

        public Resampler(string filename, int samplerate, int channels)
        {
            if (filename == null) throw new ArgumentNullException("filename");
            if (samplerate <= 0) throw new ArgumentNullException("samplerate");
            if (channels <= 0) throw new ArgumentNullException("channels");

            #region Initialize BASS stuff

            #endregion

            _filename = filename;
            _samplerate = samplerate;
            _channels = channels;
        }

        #region IDisposable Members

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion

        public void Resample(string filename)
        {
            if (filename == null) throw new ArgumentNullException("filename");
            Exceptions.ThrowIfPathInvalid(filename);

            #region Create stream and mixer

            int channel = Bass.BASS_StreamCreateFile(filename, 0, 0,
                                                     BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE |
                                                     BASSFlag.BASS_SAMPLE_FLOAT);
            if (channel == 0)
                throw new BassException("Couldn't create stream.");

            var mixer = BassMix.BASS_Mixer_StreamCreate(22050, 1, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT);
            if (mixer == 0)
                throw new BassException("Couldn't create mixer stream.");

            if (!BassMix.BASS_Mixer_StreamAddChannel(mixer, channel,
                                                     BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_FILTER |
                                                     BASSFlag.BASS_MIXER_NORAMPIN))
                throw new BassException("Couldn't add stream channel to mixer.");

            #endregion

            int sr = 22050;
            int secs = 20;
            int samples0 = sr * secs;
            var buffer = new float[samples0];
            int length = sizeof(float) * buffer.Length;
            var getData = Bass.BASS_ChannelGetData(mixer, buffer, length | (int)BASSData.BASS_DATA_FLOAT);
            if (getData != length)
            {
                throw new BassException("");
            }
            var bassMixerChannelRemove = BassMix.BASS_Mixer_ChannelRemove(channel);
            var streamFree = Bass.BASS_StreamFree(channel);
            var bassStreamFree = Bass.BASS_StreamFree(mixer);
        }
    }
}
使用系统;
使用Un4seen.Bass;
使用Un4seen.Bass.AddOn.Mix;
名称空间XXX
{
公共类重采样器:IDisposable
{
专用只读int_通道;
私有只读字符串\u文件名;
私有只读int_采样器;
公共重采样器(字符串文件名、整数采样器、整数通道)
{
如果(filename==null)抛出新的ArgumentNullException(“filename”);

如果(samplerate软件模式和/或44.1Khz没有改变任何东西。现在我要研究一下BASS.NET…基本上你需要BassMix插件,你创建一个44.1Khz混音器,然后你添加你的32Khz源;最后你播放这个混音器。如果你需要帮助,尽管问。不,我的意思是BASS不起作用。它会在样本的第一次呼叫时中断到Bass.Bass_Init()。对于这是我的第二个提示,另外,您还有GetError来了解真正发生了什么。另外,如果您使用的是64位: