public static int ConvertAndDecode(string inputFile, string inputFileType, string outputFile) { ProcessStartInfo startInfo = GetStartInfo($"ffmpeg -hide_banner -loglevel warning -i \"{inputFile}\" -f {inputFileType} - | sox -V2 -V2 -t {inputFileType} - -t raw -e signed-integer -b 16 -r 22050 - remix 1", true, true); FileStream fs = null; if (outputFile != null) { File.WriteAllText(outputFile, string.Empty); fs = new FileStream(outputFile, FileMode.OpenOrCreate); } ulong bytesReadIn = 0; using (Process soxProcess = Process.Start(startInfo)) { if (!Program.SuppressInfo) { Console.WriteLine("info: ffmpeg and sox have started"); } soxProcess.EnableRaisingEvents = true; soxProcess.BeginErrorReadLine(); soxProcess.ErrorDataReceived += new DataReceivedEventHandler((s, e) => { if (!string.IsNullOrWhiteSpace(e.Data)) { Console.WriteLine($"proc: {e.Data}\n"); // arguments have been modified in ffmpeg so that it only prints to standard error when warnings are raised or errors occur } }); FileStream baseStream = (FileStream)soxProcess.StandardOutput.BaseStream; int lastRead = 0; bool record = false; bool lastRecord = false; string fileName = null; bool needToBuffer = true; Console.WriteLine(); do // sox nor ffmpeg will not produce anything on stdout if an error occurs { byte[] buffer = new byte[8192]; lastRead = baseStream.Read(buffer, 0, buffer.Length); bytesReadIn += (ulong)lastRead; Tuple <bool, uint, uint> info = null; if (lastRead > 0) { info = Decode.DecodeEAS(buffer, lastRead); lastRecord = record; record = info.Item1; if (fs != null) { fs.Write(buffer, 0, lastRead); fs.Flush(); } } if (!record && !lastRecord) { Console.CursorTop -= 1; Console.WriteLine($"Total bytes read in: {Commas(bytesReadIn)}"); } else if (!record && lastRecord) { Console.WriteLine(); } if (bufferBefore != null) { if (needToBuffer) { for (int i = 0; i < lastRead; i++) { bufferBefore.Enqueue(buffer[i]); } if (easRecord != null && bufferBefore.Size == bufferBefore.Count) { Console.WriteLine("Stopped recording EAS alert"); SaveEASRecording(ref easRecord, bufferBefore, fileName); } } if (record && easRecord == null) { Console.WriteLine("Recording EAS alert"); DateTime recordingStarted = DateTime.Now; string month = $"{AddLeadingZero(recordingStarted.Month)}{months[recordingStarted.Month - 1]}"; string time = $"{AddLeadingZero(recordingStarted.Hour)}{AddLeadingZero(recordingStarted.Minute)}{AddLeadingZero(recordingStarted.Second)}"; fileName = $"{recordingStarted.Year}_{month}_{recordingStarted.Day} - {time}"; int idx = 1; while (File.Exists($"{fileName} ({idx}).raw")) { idx++; } fileName += $" ({idx})"; easRecord = new FileStream($"{fileName}.raw", FileMode.OpenOrCreate); while (!bufferBefore.IsEmpty) { byte[] b = new byte[1]; if (bufferBefore.TryDequeue(out b[0])) { easRecord.Write(b); } } needToBuffer = false; } else if (record && easRecord != null) { if (needToBuffer) { while (!bufferBefore.IsEmpty) { byte[] b = new byte[1]; if (bufferBefore.TryDequeue(out b[0])) { easRecord.Write(b); } needToBuffer = false; } } else { easRecord.Write(buffer, 0, lastRead); } } else if (!record && easRecord != null && !needToBuffer) { easRecord.Write(buffer, 0, lastRead); needToBuffer = true; bufferBefore = new FixedSizeQueue <byte>(bitrate * 5); } } } while (lastRead > 0); if (easRecord != null) { SaveEASRecording(ref easRecord, bufferBefore, fileName); } soxProcess.WaitForExit(); } return(0); }