public WaveOut(
        int deviceID,
        short channels,
        int samplesPerSecond,
        SPEAKER channelMask,
        Guid formatSubType,
        ILoggerFactory loggerFactory,
        ElapsedTimeCounter counter,
        ITargetBlock <PcmBuffer <T> > releaseQueue
        )
    {
        _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
        _counter       = counter ?? throw new ArgumentNullException(nameof(counter));

        ArgumentNullException.ThrowIfNull(releaseQueue);

        _logger         = _loggerFactory.CreateLogger <WaveOut <T> >();
        _headerPool     = new BufferPool <WaveHeaderBuffer>(1, () => { return(new WaveHeaderBuffer()); }, _loggerFactory);
        _driverCallBack = new PinnedDelegate <DriverCallBack.Proc>(new DriverCallBack.Proc(DriverCallBackProc));

        var format = new WaveFormatExtensible();

        format.wfe.formatType            = WaveFormatEx.FORMAT.EXTENSIBLE;
        format.wfe.channels              = (ushort)channels;
        format.wfe.samplesPerSecond      = (uint)samplesPerSecond;
        format.wfe.bitsPerSample         = (ushort)(SIZE_OF_T * 8);
        format.wfe.blockAlign            = (ushort)(format.wfe.channels * format.wfe.bitsPerSample / 8);
        format.wfe.averageBytesPerSecond = format.wfe.samplesPerSecond * format.wfe.blockAlign;
        format.wfe.size = (ushort)(Marshal.SizeOf <WaveFormatExtensiblePart>());

        format.exp.validBitsPerSample = format.wfe.bitsPerSample;
        format.exp.channelMask        = ToSPEAKER(channelMask);
        format.exp.subFormat          = formatSubType;

        //たまに失敗するので、ピン止めしておく
        using var formatPin = new PinnedBuffer <WaveFormatExtensible>(format);

        var mmResult =
            NativeMethods.waveOutOpen(
                out _handle,
                deviceID,
                ref format,
                _driverCallBack.FunctionPointer,
                IntPtr.Zero,
                (
                    DriverCallBack.TYPE.FUNCTION
                    | DriverCallBack.TYPE.WAVE_FORMAT_DIRECT
                )
                );

        if (mmResult != MMRESULT.NOERROR)
        {
            throw new WaveException(mmResult);
        }

        _releaseAction = new TransformBlock <IntPtr, PcmBuffer <T> >(headerPtr => Unprepare(headerPtr));
        _releaseAction.LinkTo(releaseQueue);
    }
        internal WindowClass(
            ILoggerFactory loggerFactory,
            PinnedDelegate <User32.WNDPROC> wndProc,
            User32.WNDCLASS.CS cs = User32.WNDCLASS.CS.NONE
            )
        {
            LoggerFactory = loggerFactory;
            Logger        = LoggerFactory.CreateLogger <WindowClass>();

            windowClass = new User32.WNDCLASS
            {
                style         = cs,
                lpfnWndProc   = wndProc.FunctionPointer,
                hInstance     = Kernel32.GetModuleHandle(default),
Example #3
0
    private const int COUNT_OF_EVENTS = 500; //サイズが適当

    internal Effect(
        string library,
        AudioMaster <T> audioMaster,
        ILoggerFactory loggerFactory,
        ElapsedTimeCounter counter
        )
    {
        _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
        _counter       = counter ?? throw new ArgumentNullException(nameof(counter));

        _logger = _loggerFactory.CreateLogger <Effect <T> >();

        _audioMaster = audioMaster;

        //TODO IPCBufferにする
        _events    = new(new byte[SIZE_OF_VSTEVENTS + (SIZE_OF_INTPTR * COUNT_OF_EVENTS)]);
        _eventList = new(new byte[SIZE_OF_VSTMIDIEVENT * COUNT_OF_EVENTS]);

        var vstPluginMain = _audioMaster.DllManager.GetExport <AEffect.VSTPluginMain>(library, "VSTPluginMain");

        if (vstPluginMain == default)
        {
            vstPluginMain = _audioMaster.DllManager.GetExport <AEffect.VSTPluginMain>(library, "main");
        }

        if (vstPluginMain == default)
        {
            throw new VstException("VSTPluginMainが取得できない");
        }

        _audioMasterCallBack = new(new(_audioMaster.AudioMasterCallBackProc));
        _aeffectPtr          = vstPluginMain(_audioMasterCallBack.FunctionPointer);
        if (_aeffectPtr == default)
        {
            throw new VstException("vstPluginMain で失敗");
        }

        var aeffect = GetAEffect();

        _logger.LogInformation($"magic:{aeffect.magic}");
        _logger.LogInformation($"dispatcher:{aeffect.dispatcher}");
        _logger.LogInformation($"processDeprecated:{aeffect.processDeprecated}");
        _logger.LogInformation($"setParameter:{aeffect.setParameter}");
        _logger.LogInformation($"getParameter:{aeffect.getParameter}");

        _logger.LogInformation($"numPrograms:{aeffect.numPrograms}");
        _logger.LogInformation($"numParams:{aeffect.numParams}");
        _logger.LogInformation($"numInputs:{aeffect.numInputs}");
        _logger.LogInformation($"numOutputs:{aeffect.numOutputs}");
        _logger.LogInformation($"flags:{aeffect.flags}");

        //Logger.LogInformation($"resvd1:"+aeffect.resvd1);
        //Logger.LogInformation($"resvd2:"+aeffect.resvd2);

        _logger.LogInformation($"initialDelay:{aeffect.initialDelay}");

        _logger.LogInformation($"realQualitiesDeprecated:{aeffect.realQualitiesDeprecated}");
        _logger.LogInformation($"offQualitiesDeprecated:{aeffect.offQualitiesDeprecated}");
        _logger.LogInformation($"ioRatioDeprecated:{aeffect.ioRatioDeprecated}");
        //Logger.LogInformation($"object:"+aeffect._object);
        _logger.LogInformation($"user:{aeffect.user}");

        _logger.LogInformation($"uniqueID:{aeffect.uniqueID}");
        _logger.LogInformation($"version:{aeffect.version}");

        _logger.LogInformation("processReplacing:" + aeffect.processReplacing);
        _logger.LogInformation("processDoubleReplacing:" + aeffect.processDoubleReplacing);

        if (aeffect.dispatcher != default)
        {
            _dispatcherProc =
                Marshal.GetDelegateForFunctionPointer <AEffect.DispatcherProc>(aeffect.dispatcher);
        }

        if (aeffect.setParameter != default)
        {
            _setParameterProc =
                Marshal.GetDelegateForFunctionPointer <AEffect.SetParameterProc>(aeffect.setParameter);
        }

        if (aeffect.getParameter != default)
        {
            _getParameterProc =
                Marshal.GetDelegateForFunctionPointer <AEffect.GetParameterProc>(aeffect.getParameter);
        }

        if (SIZE_OF_T == 4)
        {
            if (aeffect.processReplacing != default)
            {
                _processProc =
                    Marshal.GetDelegateForFunctionPointer <AEffect.ProcessProc>(aeffect.processReplacing);
            }
            else
            {
                throw new VstException("processReplacing が無い");
            }
        }
        else
        {
            if (aeffect.processDoubleReplacing != default)
            {
                _processProc =
                    Marshal.GetDelegateForFunctionPointer <AEffect.ProcessProc>(aeffect.processDoubleReplacing);
            }
            else
            {
                throw new VstException("processDoubleReplacing が無い");
            }
        }

        Open();

        _beforeTime = _counter.NowTicks;

        _audioMaster.EffectMap.Add(_aeffectPtr, this);
    }