public ProcessedMetaData ReadHeader(BinaryReader reader) { //Read the wave file header from the buffer. int headerSize = 0; int optionalSize = 0; int normalSize = 44; int chunkID = reader.ReadInt32(); int fileSize = reader.ReadInt32(); int riffType = reader.ReadInt32(); int fmtID = reader.ReadInt32(); int fmtSize = reader.ReadInt32(); int fmtCode = reader.ReadInt16(); int channels = reader.ReadInt16(); int sampleRate = reader.ReadInt32(); int fmtAvgBPS = reader.ReadInt32(); int fmtBlockAlign = reader.ReadInt16(); int bitDepth = reader.ReadInt16(); if (fmtSize == 18) { // Read any extra values int fmtExtraSize = reader.ReadInt16(); reader.ReadBytes(fmtExtraSize); optionalSize = fmtExtraSize + 2; } int dataID = reader.ReadInt32(); int dataSize = reader.ReadInt32(); headerSize = normalSize + optionalSize; ProcessedMetaData metaData = new ProcessedMetaData(channels, bitDepth, sampleRate, headerSize); return(metaData); }
/// <summary> /// Main method for processing the whole music sample /// </summary> /// <param name="inputFilePath"></param> /// <param name="outputFileName"></param> /// <param name="form"></param> public void ProcessSoundFile(string inputFilePath, string outputFileName, SoundVisualizer form) { if (form.filesToProcess != null) { Monitor.Exit(form.filesToProcess); } #region processing header BinaryReader headerStream = new BinaryReader(File.Open(inputFilePath, FileMode.Open)); ISoundReader soundReader = new WavSoundReader(); ProcessedMetaData metaData = soundReader.ReadHeader(headerStream); SampleSize = metaData.channelsCount * metaData.bitDepth / 8; sampleArraySize = (ChunkSize / SampleSize) + 1; headerStream.Close(); #endregion #region skipping header FileStream dataStream = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read); dataStream.Seek(metaData.headerSize, SeekOrigin.Begin); #endregion #region processing data Complex[] complexSamples = new Complex[sampleArraySize]; Complex[] extendedComplexSamples = new Complex[2 * sampleArraySize - 2]; IWindowFunction window = new HannWindowFunction(); byte[] byteValues = soundReader.ReadDataBuffer(dataStream, ChunkSize + SampleSize); MusicSample musicSample = new MusicSample(metaData, inputFilePath); musicSample.Notes = new List <Note>(); while (dataStream.Position < dataStream.Length - ChunkSize) { complexSamples = ToComplexSamples(metaData.channelsCount == 1 ? byteValues : ExtractByteChannel(byteValues, isEven: true), metaData.bitDepth, metaData.channelsCount); INoiseDetector noiseDetector = new RMSNoiseDetector(2 << (metaData.bitDepth - 1)); if (noiseDetector.IsNoise(complexSamples)) { Note detectedNote = new Pause(); musicSample.Notes.Add(detectedNote); } else { extendedComplexSamples = ExtendSamples(complexSamples); window.Windowify(extendedComplexSamples); extendedComplexSamples = extendedComplexSamples.MakeFFT().MakeHPS(HPSIterationsCount); MaxFreqBin maxFreqBin = GetMaxFreqBin(extendedComplexSamples); double maxFreq = CalculateMaxFreq(maxFreqBin.BinNumber, metaData, sampleArraySize); NoteDetector noteDetector = new NoteDetector(); Note detectedNote = noteDetector.GetClosestNote(maxFreq / 2); musicSample.Notes.Add(detectedNote); } soundReader.MoveDataBuffer(dataStream, window.OverlapSize, byteValues); } IErrorCorrector corrector = new OverlapWindowCorrector(); corrector.Correct(musicSample); INoteLengthProcessor noteLengthProcessor = new DefaultNoteLengthProcessor(); noteLengthProcessor.ProcessSample(musicSample); StreamWriter writer2 = new StreamWriter(outputFileName); INoteWriter noteWriter = new LillyPondNoteWriter(); noteWriter.WriteAll(musicSample, writer2); #endregion }
private double CalculateMaxFreq(int maxAmplitudeIndex, ProcessedMetaData metaData, int samplesCount) { return(((double)maxAmplitudeIndex * metaData.sampleFreq / samplesCount)); }
public MusicSample(ProcessedMetaData metaData, string sourceName) { this.metaData = metaData; this.sourceName = sourceName; }