public async void WillBackupIfRequested() { var backupPath = this.target.Path + ".bak"; var dryRun = new DryRun(false, this.dryRunLogger); var before = await this.fileUtilities.CalculateChecksum(this.target.Path, HashAlgorithmName.SHA256); await this.AssertMetadata(BeforeFixSamples, FirmwareVersion); var actual = await this.fixer.ProcessFileAsync(this.target.Path, dryRun, true); Assert.Equal(FixStatus.Fixed, actual.Status); Assert.Contains($"Old total samples was", actual.Message); // modified file await this.AssertMetadata(AfterFixSamples, FirmwareVersion, PatchedTag); // backup using (var stream = (FileStream)this.fileSystem.File.OpenRead(backupPath)) { var actualSamples = (ulong)Flac.ReadTotalSamples(stream); var actualFirmware = (FirmwareRecord) await ReadFirmwareAsync(stream); Assert.Equal(BeforeFixSamples, actualSamples); Assert.Equal(FirmwareVersion, actualFirmware.Version); actualFirmware.Tags.Should().BeEquivalentTo(Array.Empty <string>()); } var after = await this.fileUtilities.CalculateChecksum(backupPath, HashAlgorithmName.SHA256); // the backup file has the same hash as the original Assert.Equal(before, after); }
public void ReadBitDepthTest(FixtureModel model) { if (model.Process.ContainsKey(FixtureModel.FlacHeaderExtractor)) { Fin <byte> bitDepth = Flac.ReadBitDepth(model.ToTargetInformation(this.RealFileSystem).FileStream); Assert.True(bitDepth.IsSucc); ((byte)bitDepth).Should().Be(model.Record.BitDepth); } }
public void ReadNumChannelsTest(FixtureModel model) { if (model.Process.ContainsKey(FixtureModel.FlacHeaderExtractor)) { Fin <byte> channels = Flac.ReadNumChannels(model.ToTargetInformation(this.RealFileSystem).FileStream); Assert.True(channels.IsSucc); ((byte)channels).Should().Be((byte)model.Record.Channels); } }
public void ReadSampleRateTest(FixtureModel model) { if (model.Process.ContainsKey(FixtureModel.FlacHeaderExtractor)) { Fin <uint> sampleRate = Flac.ReadSampleRate(model.ToTargetInformation(this.RealFileSystem).FileStream); Assert.True(sampleRate.IsSucc); ((uint)sampleRate).Should().Be(model.Record.SampleRateHertz); } }
public void ReadTotalSamplesTest(FixtureModel model) { if (model.Process.ContainsKey(FixtureModel.FlacHeaderExtractor)) { Fin <ulong> totalSamples = Flac.ReadTotalSamples(model.ToTargetInformation(this.RealFileSystem).FileStream); Assert.True(totalSamples.IsSucc); ((ulong)totalSamples).Should().Be(model.Record.TotalSamples); } }
private async Task AssertMetadata(ulong samples, decimal firmwareVersion, params string[] tags) { using var stream = (FileStream) this.fileSystem.File.OpenRead(this.target.Path); var actualSamples = (ulong)Flac.ReadTotalSamples(stream); var actualFirmware = (FirmwareRecord) await ReadFirmwareAsync(stream); Assert.Equal(samples, actualSamples); Assert.Equal(firmwareVersion, actualFirmware.Version); actualFirmware.Tags.Should().BeEquivalentTo(tags); }
public static async ValueTask <Fin <FirmwareRecord> > ReadFirmwareAsync(FileStream stream) { var vorbisChunk = Flac.ScanForChunk(stream, Flac.VorbisCommentBlockNumber); if (vorbisChunk.IsFail) { return((Error)vorbisChunk); } var vorbisSpan = await RangeHelper.ReadRangeAsync(stream, (RangeHelper.Range) vorbisChunk); // find the frontier labs vorbis vendor comment return(FindInBufferFirmware(vorbisSpan, ((RangeHelper.Range)vorbisChunk).Start)); }
public ValueTask <Recording> ProcessFileAsync(TargetInformation information, Recording recording) { var samples = Flac.ReadTotalSamples(information.FileStream); var sampleRate = Flac.ReadSampleRate(information.FileStream); var channels = Flac.ReadNumChannels(information.FileStream); var bitDepth = Flac.ReadBitDepth(information.FileStream); Rational?duration = samples.IsFail || sampleRate.IsFail || (uint)sampleRate == 0 ? null : (new Rational((ulong)samples) / new Rational((uint)sampleRate)); uint? bitRate = sampleRate.IsFail || bitDepth.IsFail || channels.IsFail ? null : (uint)sampleRate * (uint)bitDepth * (uint)channels; recording = recording with { DurationSeconds = recording.DurationSeconds ?? duration, SampleRateHertz = recording.SampleRateHertz ?? (sampleRate.IsFail ? null : (uint)sampleRate), TotalSamples = recording.TotalSamples ?? (samples.IsFail ? null : (ulong)samples), Channels = recording.Channels ?? (channels.IsFail ? null : (byte)channels), BitDepth = recording.BitDepth ?? (bitDepth.IsFail ? null : (byte)bitDepth), BitsPerSecond = recording.BitsPerSecond ?? bitRate, }; return(ValueTask.FromResult(recording)); }
public void HasMetadataBlockTest(FixtureModel model) { bool hasMetadata = Flac.HasMetadataBlock(model.ToTargetInformation(this.RealFileSystem).FileStream).IfFail(false); ((bool)hasMetadata).Should().Be(model.IsFlac && model.ValidMetadata != ValidMetadata.No); }
public void IsFlacFileTest(FixtureModel model) { bool isFlac = Flac.IsFlacFile(model.ToTargetInformation(this.RealFileSystem).FileStream).IfFail(false); isFlac.Should().Be(model.IsFlac); }
public ValueTask <Recording> ProcessFileAsync(TargetInformation information, Recording recording) { var tryComments = Flac.ExtractComments(information.FileStream); if (tryComments.IsSucc) { Dictionary <string, string> comments = (Dictionary <string, string>)tryComments; Dictionary <string, double> location = (Dictionary <string, double>) this.ParseComment(FrontierLabs.LocationCommentKey, comments); Dictionary <string, object> sdCid = (Dictionary <string, object>) this.ParseComment(FrontierLabs.SdCidCommentKey, comments); List <Microphone> microphones = new List <Microphone>(); int micNumber = 1; // Extract all microphone information while (comments.ContainsKey(FrontierLabs.MicrophoneTypeCommentKey + micNumber)) { // FL uses channel A, B to refer to microphones 1 and 2 respectively // Converts to channel name using ASCII value offset of 64 string channelName = ((char)(micNumber + 64)).ToString(); Microphone microphone = new Microphone() with { Type = (string)this.ParseComment(FrontierLabs.MicrophoneTypeCommentKey + micNumber, comments), UID = (string)this.ParseComment(FrontierLabs.MicrophoneUIDCommentKey + micNumber, comments), BuildDate = (LocalDate?)this.ParseComment(FrontierLabs.MicrophoneBuildDateCommentKey + micNumber, comments), Gain = (double?)this.ParseComment(FrontierLabs.MicrophoneGainCommentKey + micNumber, comments), Channel = micNumber, ChannelName = channelName, }; if (microphone.Type != null) { microphones.Add(microphone); } micNumber++; } // Extract battery related values // Two batter values are extracted from the same comment as a tuple var batteryValues = ((double?, double?)?) this.ParseComment(FrontierLabs.BatteryLevelCommentKey, comments); double?batteryLevel = null, voltage = null; if (batteryValues != null) { batteryLevel = batteryValues?.Item1; batteryLevel = batteryLevel == null ? null : batteryLevel / 100; voltage = batteryValues?.Item2; } // Update recording information with parsed comments recording = recording with { Sensor = (recording.Sensor ?? new Sensor()) with { Firmware = recording.Sensor?.Firmware ?? (string)this.ParseComment(FrontierLabs.FirmwareCommentKey, comments), BatteryLevel = recording.Sensor?.BatteryLevel ?? batteryLevel, Voltage = recording.Sensor?.Voltage ?? voltage, LastTimeSync = recording.Sensor?.LastTimeSync ?? (OffsetDateTime?)this.ParseComment(FrontierLabs.LastSyncCommentKey, comments), SerialNumber = recording.Sensor?.SerialNumber ?? (string)this.ParseComment(FrontierLabs.SensorIdCommentKey, comments), Microphones = recording.Sensor?.Microphones ?? new Microphone[microphones.Length()], },