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),
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); }