예제 #1
0
파일: InputDevice.cs 프로젝트: desla/AS
        /// <summary>
        /// Начинает запись звука на канале.
        /// </summary>
        /// <param name="aInChannelNumber">Номер канала.</param>
        /// <param name="aOutChannelsIds">Идентификаторы выходных каналов.</param>
        /// <param name="aRecordOwner">Инициатор записи.</param>
        public void StartRecord(int aInChannelNumber, int[] aOutChannelsIds, int aRecordOwner)
        {
            lock (stopRecordLock) {
                if (isBusy) {
                    return;
                }

                isBusy = true;

                var bytePerSecond = samplePerSec*bytePerSample*channelsCount;

                var bufferLength = seconds*bytePerSecond;

                currentWaveInHdr = new WAVEHDR {
                    LpData = Marshal.AllocHGlobal(bufferLength),
                    DwBufferLength = (uint) (bufferLength),
                    DwBytesRecorded = 0,
                    DwUser = IntPtr.Zero,
                    DwFlags = 0,
                    DwLoops = 0
                };

                NativeMethods.waveInPrepareHeader(handle, ref currentWaveInHdr,
                    (uint) Marshal.SizeOf(typeof (WAVEHDR)));

                currentInChannelId = aInChannelNumber;
                currentOutChannelsIds = aOutChannelsIds;
                currentRecordOwner = aRecordOwner;

                recordControlThread = new Thread(() => RecordControlMethod(aInChannelNumber, aRecordOwner));
                recordControlThread.Start();

                NativeMethods.waveInAddBuffer(handle, ref currentWaveInHdr,
                    (uint) Marshal.SizeOf(typeof (WAVEHDR)));
                NativeMethods.waveInStart(handle);
            }
        }
예제 #2
0
파일: OutputDevice.cs 프로젝트: desla/AS
        /// <summary>
        /// Записываем звук в буфер устройства.
        /// </summary>
        /// <param name="aSoundData">Записываемые данные.</param>
        /// <param name="aChannelId">Номер канала воспроизведения. Если -1 => воспроизводим на всех каналах.</param>
        public void WriteDataToChannel(byte[] aSoundData, int aChannelId)
        {
            if (aSoundData == null) {
                throw new ArgumentNullException("aSoundData");
            }

            if (aChannelId < -1 || aChannelId >= channelsCount) {
                throw new ArgumentException(string.Format("ChannelId={0} is out of range [0 - {1}]", aChannelId, channelsCount - 1));
            }

            var dataLength = aSoundData.Length;

            var soundDataCopy = new byte[dataLength];
            aSoundData.CopyTo(soundDataCopy, 0);

            if (aChannelId != -1) {
                ForbidChannelsExcept(soundDataCopy, aChannelId);
            }

            var pSoundData = Marshal.AllocHGlobal(dataLength);

            try {
                Marshal.Copy(soundDataCopy, 0, pSoundData, dataLength);

                var waveHdr = new WAVEHDR {
                    LpData = pSoundData,
                    DwBufferLength = (uint) dataLength,
                    DwFlags = 0,
                    DwLoops = 0
                };

                lock (writingLock) {
                    var stepNumber = 0;
                    var stepSpeed = 100; // миллисекунды
                    var bytePerStep = 2*bytePerSample*samplePerSec*stepSpeed/1000;

                    NativeMethods.waveOutPrepareHeader(this.handle, ref waveHdr, (uint) Marshal.SizeOf(typeof (WAVEHDR)));
                    NativeMethods.waveOutWrite(this.handle, ref waveHdr, (uint) Marshal.SizeOf(typeof (WAVEHDR)));

                    // ожидаем окончания воспроизведения и меняем текущий уровень на каналах
                    while ((waveHdr.DwFlags & WAVEHDRFLAGS.WHDR_DONE) == 0) {
                        var dataIndex = stepNumber*bytePerStep + aChannelId*2;
                        if (dataIndex < dataLength) {
                            var value = soundDataCopy[dataIndex] << 5;
                            channelLevels[aChannelId] = value;
                            //Logger.Info(value);
                            stepNumber++;
                        }

                        Thread.Sleep(stepSpeed);
                    }

                    channelLevels[aChannelId] = 0;

                    NativeMethods.waveOutUnprepareHeader(this.handle, ref waveHdr,
                        (uint) Marshal.SizeOf(typeof (WAVEHDR)));
                    NativeMethods.waveOutReset(this.handle);
                }
            }
            finally {
                // Освободим неуправляемую память
                Marshal.FreeHGlobal(pSoundData);
            }
        }
예제 #3
0
파일: DllImports.cs 프로젝트: desla/AS
 public static extern uint waveOutWrite(IntPtr hWaveOut, ref WAVEHDR pwh, uint cbwh);
예제 #4
0
파일: DllImports.cs 프로젝트: desla/AS
 public static extern uint waveOutUnprepareHeader(IntPtr hWaveOut, ref WAVEHDR pwh, uint cbwh);
예제 #5
0
파일: DllImports.cs 프로젝트: desla/AS
 public static extern uint waveOutPrepareHeader(IntPtr hWaveOut, ref WAVEHDR lpWaveOutHdr, uint uSize);
예제 #6
0
파일: DllImports.cs 프로젝트: desla/AS
 public static extern uint waveInPrepareHeader(IntPtr hWaveIn, ref WAVEHDR pwh, uint cbwh);
예제 #7
0
파일: DllImports.cs 프로젝트: desla/AS
 public static extern uint waveInAddBuffer(IntPtr hWaveIn, ref WAVEHDR pwh, uint cbwh);