NateRickard / Plugin.AudioRecorder

Audio Recorder plugin for Xamarin and Windows
MIT License
164 stars 68 forks source link

iOS concurrent Stream is empty / has no length #59

Open th3-sh0w3r opened 3 years ago

th3-sh0w3r commented 3 years ago

Hey,

I'm trying to send bytes from the audio stream to my microcontroller. Issue here is that the audio stream has a length of 0 and it doesn't change. I also checked that the permissions are set and that the microphone recording is allowed in the settings.

Details: iPhone 8 Plus Newest iOS version

I went through all issues here and tried everything I could but nothing works. Last thing I tried was this: https://github.com/NateRickard/Plugin.AudioRecorder/issues/38

This is my code (yes _recorder.StartRecording() is called before) a part of it is from your Xamarin.Cognitive.Speech plugin

private async Task CompileAudio()
        {
            using Stream audioStream = _recorder.GetAudioFileStream();
            const int audioDataWaitInterval = 100; //ms
            const int maxReadRetries = 10; //times
            const int ChunkSize = 1024;
            const int streamReadDelay = 30;

            try
            {
                byte[] buffer = null;
                int bytesRead = 0;
                int readRetryCount = 0;

                if (audioStream.CanRead)
                {
                    var totalWait = 0;

                    while (audioStream.Length < ChunkSize && totalWait < audioDataWaitInterval * maxReadRetries)
                    {
                        await Task.Delay(audioDataWaitInterval);
                        totalWait += audioDataWaitInterval;
                    }

                   Console.WriteLine("Length: " + audioStream.Length);

                    buffer = new byte[checked((uint)Math.Min(ChunkSize, (int)audioStream.Length))];

                    var tcs = new TaskCompletionSource<bool>();
                    var waitTask = _recordTask ?? tcs.Task;

                    while (audioStream.CanRead && ((bytesRead = await audioStream.ReadAsync(buffer, 0, buffer.Length)) != 0 || !waitTask.Wait(streamReadDelay)))
                    {
                        if (bytesRead > 0)
                        {
                            readRetryCount = -1;

                            Console.WriteLine("Read: " + bytesRead);

                            if (_cancelSource.IsCancellationRequested)
                            {
                                break;
                            }

                            for (int i = 0; i < _samples; i++)
                            {
                                _micData = BitConverter.ToUInt16(buffer, 0);
                                Console.WriteLine("MicData: " + _micData.ToString());
                                _vReal[i] = _micData;
                                _vImag[i] = 0;
                            }
                        }

                        readRetryCount++;

                        if (_recordTask == null && readRetryCount >= maxReadRetries)
                        {
                            tcs.SetResult(true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("CompileAudio: " + ex.ToString());
                throw;
            }
            finally
            {
                audioStream.Close();
            }
      }

EDIT: Shorten the code