/// <summary>
        /// Accepts Base64 data encoded as a char array and writes it to the binary stream.
        /// </summary>
        /// <param name="buffer">Array of char representing the base64 data</param>
        /// <param name="offset">Zero based element position to start encoding</param>
        /// <param name="count">The Number of chars to decode</param>
        /// <returns>The number of bytes consumed by the conversion (which may not be the whole array)</returns>
        public async Task <int> Write(char[] buffer, int offset, int count)
        {
            // must write in multiples of 4.  We need to add any unwritten buffer to the front
            var charsToWrite      = 4 * ((int)((count + unwritten.Length) / 4));
            var newChars          = new char[charsToWrite];
            var newDataStartPoint = unwritten.Length;
            var newCount          = charsToWrite - unwritten.Length;

            if (unwritten.Length > 0)
            {
                Array.Copy(unwritten.ToCharArray(), 0, newChars, 0, unwritten.Length);
            }
            ;
            Array.Copy(buffer, 0, newChars, newDataStartPoint, newCount);
            var newBytes = Convert.FromBase64CharArray(newChars, 0, charsToWrite);

            //keep the unwritten part for next time.
            var unwrittenSize = (count - newCount);

            if (unwrittenSize > 0)
            {
                unwritten = new string(buffer, count - unwrittenSize, unwrittenSize);
            }
            if (!Ignore)
            {
                await OutStream.WriteAsync(newBytes, 0, newBytes.Length);
            }
            return(charsToWrite);
        }
예제 #2
0
 public Task WriteAsync(int value, CancellationToken cancellationToken)
 {
     byte[] buffer = Buffer;
     buffer[0] = (byte)value;
     buffer[1] = (byte)(value >> 8);
     buffer[2] = (byte)(value >> 16);
     buffer[3] = (byte)(value >> 24);
     return(OutStream.WriteAsync(buffer, 0, 4, cancellationToken));
 }
예제 #3
0
 public Task WriteAsync(long value, CancellationToken cancellationToken)
 {
     byte[] buffer = Buffer;
     buffer[0] = (byte)value;
     buffer[1] = (byte)(value >> 8);
     buffer[2] = (byte)(value >> 16);
     buffer[3] = (byte)(value >> 24);
     buffer[4] = (byte)(value >> 32);
     buffer[5] = (byte)(value >> 40);
     buffer[6] = (byte)(value >> 48);
     buffer[7] = (byte)(value >> 56);
     return(OutStream.WriteAsync(buffer, 0, 8, cancellationToken));
 }
        /// <summary>
        /// Accepts Base64 String data converts it to the binary stream
        /// </summary>
        /// <param name="text">A Snippet of Base64 text to be written to the stream</param>
        /// <returns>The number of characters consumed by the conversion (which may NOT be the whole string)</returns>
        public async Task <int> WriteString(string text)
        {
            var textToWrite  = unwritten + text;
            var charsToWrite = 4 * ((int)(textToWrite.Length / 4));
            var newChars     = Convert.FromBase64String(textToWrite.Substring(0, charsToWrite));

            unwritten = (charsToWrite < textToWrite.Length) ? textToWrite.Substring(charsToWrite) : "";
            if (!Ignore)
            {
                await OutStream.WriteAsync(newChars, 0, newChars.Length);
            }
            return(charsToWrite);
        }
예제 #5
0
        protected virtual async Task WriteHeaderAsync(string name, DateTime lastModificationTime, long count,
                                                      string userName, string groupName, int mode)
        {
            var tarHeader = new UsTarHeader()
            {
                FileName         = name,
                LastModification = lastModificationTime,
                SizeInBytes      = count,
                UserId           = userName.GetHashCode(),
                UserName         = userName,
                GroupId          = groupName.GetHashCode(),
                GroupName        = groupName,
                Mode             = mode
            };

            await OutStream.WriteAsync(tarHeader.GetHeaderValue(), 0, tarHeader.HeaderSize);
        }
예제 #6
0
        protected override async Task WriteHeaderAsync(string name, DateTime lastModificationTime,
                                                       long count, int userId, int groupId, int mode, EntryType entryType)
        {
            var tarHeader = new UsTarHeader()
            {
                FileName         = name,
                LastModification = lastModificationTime,
                SizeInBytes      = count,
                UserId           = userId,
                UserName         = Convert.ToString(userId, 8),
                GroupId          = groupId,
                GroupName        = Convert.ToString(groupId, 8),
                Mode             = mode,
                EntryType        = entryType
            };

            await OutStream.WriteAsync(tarHeader.GetHeaderValue(), 0, tarHeader.HeaderSize);
        }
예제 #7
0
        /// <summary>
        /// Start service loop.
        /// </summary>
        private async Task StartAsyncSend()
        {
            Running = true;

            while (Running)
            {
                if (OutStream == null || !OutStream.CanWrite)
                {
                    Thread.Sleep(100);
                    continue;
                }

                try
                {
                    if (AudioQueue.Count > 0)
                    {
                        byte[] mixed = new byte[AudioHelpers.BUFFER_SIZE * AudioHelpers.CHANNEL_COUNT];

                        for (int i = 0; i < AudioHelpers.FRAME_SAMPLES; ++i)
                        {
                            int sample = 0;
                            foreach (var audioPair in AudioQueue)
                            {
                                var session = audioPair.Value;

                                if (session.State == ReproductionState.Paused)
                                {
                                    continue;
                                }

                                if (session.State == ReproductionState.Stopped)
                                {
                                    session.CloseReproduction();
                                }

                                if (session.State == ReproductionState.Closed || session.EndOfStream)
                                {
                                    AudioQueue.TryRemove(audioPair.Key, out var e);
                                    continue;
                                }

                                double volume = Math.Max(Math.Min((session.Source?.Volume ?? DefaultAudioSource.Instance.Volume) / 100, 1), 0);
                                double gain   = (session.Source?.Gain ?? DefaultAudioSource.Instance.Gain) + 1;

                                byte[] buffer = new byte[AudioHelpers.SAMPLE_SIZE];
                                if (session.Read(buffer, 0, AudioHelpers.SAMPLE_SIZE) > 0)
                                {
                                    sample += (Int32)(AudioHelpers.GetInt16(buffer, 0, true) * volume * gain);
                                }
                            }

                            short sampleValue = (short)Math.Min(Math.Max(short.MinValue, sample), short.MaxValue);

                            AudioHelpers.GetBytes(sampleValue, mixed, i * AudioHelpers.SAMPLE_SIZE, true);
                        }

                        // Send the buffer to Discord
                        await OutStream.WriteAsync(mixed, 0, AudioHelpers.FRAME_SAMPLES *AudioHelpers.CHANNEL_COUNT);
                    }
                    else
                    {
                        // Flush stream
                        await OutStream.FlushAsync();

                        Thread.Sleep(100);
                    }
                }
                catch (Exception e)
                {
                }
            }

            await Task.CompletedTask;
        }
예제 #8
0
파일: AudioBuffer.cs 프로젝트: ItsKaa/Ditto
        public void Start()
        {
            Stop();
            Running = true;
            _cancellationTokenSource = new CancellationTokenSource();

            ReadFinished = false;
            _readTask    = Task.Run(async() =>
            {
                while (Running && _cancellationTokenSource?.IsCancellationRequested == false)
                {
                    try
                    {
                        if (InStream.CanRead)
                        {
                            AudioChunk chunk = new AudioChunk(BufferReadSize);

                            int bytesRead = await InStream.ReadAsync(chunk.Memory, _cancellationTokenSource.Token).ConfigureAwait(false);
                            if (bytesRead > 0)
                            {
                                chunk.Length = bytesRead;

                                // Wait for the dequeue, comparing in megabytes.
                                while (Running && (Queue.Count * (BufferReadSize * 0.000001)) > BufferLimit)
                                {
                                    await Task.Delay(100, _cancellationTokenSource?.Token ?? CancellationToken.None).ConfigureAwait(false);
                                }
                                Queue.Enqueue(chunk);
                            }
                            else
                            {
                                Log.Debug("AudioBuffer: Read EOF");
                                break;
                            }
                        }
                        else
                        {
                            Log.Error("AudioBuffer: Could not read InStream.");
                            await Task.Delay(25).ConfigureAwait(false);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return;
                    }
                    catch (Exception ex)
                    {
                        Log.Error($"AudioBuffer | {ex}");
                    }
                }

                ReadFinished = true;
            }, _cancellationTokenSource.Token);

            _writeTask = Task.Run(async() =>
            {
                while (Running && _cancellationTokenSource?.IsCancellationRequested == false)
                {
                    if (ReadFinished && Queue.IsEmpty)
                    {
                        break;
                    }

                    try
                    {
                        if (Queue.TryDequeue(out var audioChunk))
                        {
                            using (audioChunk)
                            {
                                if (OutStream.CanWrite)
                                {
                                    // We're required to process the chunks in the write task, it's far slower which allows us to change the volume while it's still playing.
                                    if (ProcessBuffer != null)
                                    {
                                        var bytes = audioChunk.Memory;
                                        if (audioChunk.Length != audioChunk.Memory.Length)
                                        {
                                            bytes = audioChunk.Memory.Part(0, audioChunk.Length, false).ToArray();
                                        }
                                        var processedBytes = ProcessBuffer?.Invoke(bytes);
                                        processedBytes.CopyTo(audioChunk.Memory, 0);
                                        audioChunk.Length = processedBytes.Length;
                                    }

                                    await OutStream.WriteAsync(audioChunk.Memory, 0, audioChunk.Length, _cancellationTokenSource.Token);
                                }
                                else
                                {
                                    Log.Error("AudioBuffer: Could not write to OutStream.");
                                    await Task.Delay(25).ConfigureAwait(false);
                                }
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return;
                    }
                    catch (Exception ex)
                    {
                        Log.Error($"AudioBuffer | {ex.Message}");
                        Log.Debug($"AudioBuffer | {ex}");
                        await Task.Delay(25).ConfigureAwait(false);
                    }
                }
            }, _cancellationTokenSource.Token);
        }
예제 #9
0
 public Task WriteAsync(byte[] buffer, int index, int count, CancellationToken cancellationToken)
 {
     return(OutStream.WriteAsync(buffer, index, count, cancellationToken));
 }
예제 #10
0
 public Task WriteAsync(byte[] buffer, CancellationToken cancellationToken)
 {
     return(OutStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken));
 }
예제 #11
0
 public Task WriteAsync(byte value, CancellationToken cancellationToken)
 {
     Debug.Assert(value <= 18);
     return(OutStream.WriteAsync(ByteValueBuffer, value, 1, cancellationToken));
 }
예제 #12
0
 public Task WriteAsync(bool value, CancellationToken cancellationToken)
 {
     return(OutStream.WriteAsync(ByteValueBuffer, value ? 1 : 0, 1, cancellationToken));
 }