public bool Read(string filePath) { if (File.Exists(filePath)) { string fileName = Path.GetFileNameWithoutExtension(filePath); PresetName = fileName; BinaryFile bFile = new BinaryFile(filePath, BinaryFile.ByteOrder.BigEndian); string firstChunkID = bFile.ReadString(4); // chunk ID = "FORM" int ckSize = bFile.ReadInt32(); string formType = bFile.ReadString(4); // read first data chunk string chunkID = bFile.ReadString(4); // if chunkID == "COMT" then CommentsChunk if (chunkID.Equals("COMT")) { long curposTmpComt = bFile.GetPosition(); bFile.Seek(curposTmpComt-4); // CommentsChunk string chunkIDComt = bFile.ReadString(4); // chunk ID = "COMT" int chunkSizeComt = bFile.ReadInt32(); int numComments = bFile.ReadUInt16(); long curposTmpComt2 = bFile.GetPosition(); //comments = bFile.ReadString(chunkSizeComt-2); for (int i = 0; i < numComments; i++) { int commentTimestamp = (int) bFile.ReadUInt32(); string marker = bFile.ReadString(4); int count = (int) bFile.ReadByte(); comments.Add(bFile.ReadString(count)); } bFile.Seek(curposTmpComt2+chunkSizeComt-2); } string chunkID2 = bFile.ReadString(4); // if chunkID2 == "COMM" then CommonChunk if (chunkID2.Equals("COMM")) { long curposTmpComm = bFile.GetPosition(); bFile.Seek(curposTmpComm-4); // CommonChunk string chunkIDComm = bFile.ReadString(4); // chunk ID = "COMM" int chunkSizeComm = bFile.ReadInt32(); channels = bFile.ReadInt16(); numSampleFrames = (int) bFile.ReadUInt32(); bitsPerSample = bFile.ReadInt16(); // read IEEE 80-bit extended double precision byte[] sampleRateBytes = bFile.ReadBytes(0, 10, BinaryFile.ByteOrder.LittleEndian); double sampleRateDouble = NAudio.Utils.IEEE.ConvertFromIeeeExtended(sampleRateBytes); sampleRate = (int) sampleRateDouble; } string chunkID3 = bFile.ReadString(4); // if chunkID3 == "SSND" then SoundDataChunk if (chunkID3.Equals("SSND")) { long curposTmpSsnd = bFile.GetPosition(); bFile.Seek(curposTmpSsnd-4); // SoundDataChunk string chunkIDSsnd = bFile.ReadString(4); // chunk ID = "SSND" int chunkSizeSsnd = bFile.ReadInt32(); int offset = (int) bFile.ReadUInt32(); int blocksize = (int) bFile.ReadUInt32(); byte[] data = bFile.ReadBytes(offset, chunkSizeSsnd-8, BinaryFile.ByteOrder.LittleEndian); // swap waveform data WaveformData = SwapAiffEndian(data); } bFile.Close(); return true; } else { return false; } }
public bool Process() { int bytespersec = 0; int byteread = 0; bool isPCM = false; var listinfo = new Dictionary <string, string>(); for (int i = 0; i < infotype.Length; i++) { listinfo.Add(infotype[i], infodesc[i]); } var bf = new BinaryFile(selectedFile); try { var fileInfo = new FileInfo(selectedFile); fileLength = fileInfo.Length; int chunkSize = 0, infochunksize = 0, bytecount = 0, listbytecount = 0; string sfield = "", infofield = "", infodescription = "", infodata = ""; /* -------- Get RIFF chunk header --------- */ sfield = bf.ReadString(4); #if DEBUG Console.WriteLine("RIFF Header: {0}", sfield); #endif if (sfield != "RIFF") { Console.WriteLine(" **** Not a valid RIFF file ****"); return(false); } // read RIFF data size chunkSize = bf.ReadInt32(); #if DEBUG Console.WriteLine("RIFF data size: {0}", chunkSize); #endif // read form-type (WAVE etc) sfield = bf.ReadString(4); #if DEBUG Console.WriteLine("Form-type: {0}", sfield); #endif riffDataSize = chunkSize; bytecount = 4; // initialize bytecount to include RIFF form-type bytes. while (bytecount < riffDataSize) // check for chunks inside RIFF data area. { sfield = ""; int firstbyte = bf.ReadByte(); if (firstbyte == 0) // if previous data had odd bytecount, was padded by null so skip { bytecount++; continue; } sfield += (char)firstbyte; // if we have a new chunk for (int i = 1; i <= 3; i++) { sfield += (char)bf.ReadByte(); } chunkSize = 0; chunkSize = bf.ReadInt32(); bytecount += (8 + chunkSize); #if DEBUG Console.WriteLine("{0} ----- data size: {1} bytes", sfield, chunkSize); #endif if (sfield == "data") { //get data size to compute duration later. dataSize = chunkSize; } if (sfield == "fmt ") { /* * Offset Size Description Value * 0x00 4 Chunk ID "fmt " (0x666D7420) * 0x04 4 Chunk Data Size 16 + extra format bytes * 0x08 2 Compression code 1 - 65,535 * 0x0a 2 Number of channels 1 - 65,535 * 0x0c 4 Sample rate 1 - 0xFFFFFFFF * 0x10 4 Average bytes per second 1 - 0xFFFFFFFF * 0x14 2 Block align 1 - 65,535 * 0x16 2 Significant bits per sample 2 - 65,535 * 0x18 2 Extra format bytes 0 - 65,535 * 0x1a * Extra format bytes * */ // extract info from "format" chunk. if (chunkSize < 16) { Console.WriteLine(" **** Not a valid fmt chunk ****"); return(false); } // Read compression code, 2 bytes wFormatTag = bf.ReadInt16(); switch (wFormatTag) { case WAVE_FORMAT_PCM: case WAVE_FORMAT_EXTENSIBLE: case WAVE_FORMAT_IEEE_FLOAT: isPCM = true; break; } switch (wFormatTag) { case WAVE_FORMAT_PCM: Console.WriteLine("\twFormatTag: WAVE_FORMAT_PCM"); break; case WAVE_FORMAT_EXTENSIBLE: Console.WriteLine("\twFormatTag: WAVE_FORMAT_EXTENSIBLE"); break; case WAVE_FORMAT_IEEE_FLOAT: Console.WriteLine("\twFormatTag: WAVE_FORMAT_IEEE_FLOAT"); break; case WAVE_FORMAT_MPEGLAYER3: Console.WriteLine("\twFormatTag: WAVE_FORMAT_MPEGLAYER3"); break; default: Console.WriteLine("\twFormatTag: non-PCM format {0}", wFormatTag); break; } // Read number of channels, 2 bytes nChannels = bf.ReadInt16(); #if DEBUG Console.WriteLine("\tnChannels: {0}", nChannels); #endif // Read sample rate, 4 bytes nSamplesPerSec = bf.ReadInt32(); #if DEBUG Console.WriteLine("\tnSamplesPerSec: {0}", nSamplesPerSec); #endif // Read average bytes per second, 4 bytes nAvgBytesPerSec = bf.ReadInt32(); bytespersec = nAvgBytesPerSec; #if DEBUG Console.WriteLine("\tnAvgBytesPerSec: {0}", nAvgBytesPerSec); #endif // Read block align, 2 bytes nBlockAlign = bf.ReadInt16(); #if DEBUG Console.WriteLine("\tnBlockAlign: {0}", nBlockAlign); #endif // Read significant bits per sample, 2 bytes if (isPCM) // if PCM or EXTENSIBLE format { wBitsPerSample = bf.ReadInt16(); #if DEBUG Console.WriteLine("\twBitsPerSample: {0}", wBitsPerSample); #endif } else { bf.ReadBytes(2); wBitsPerSample = 0; } //skip over any extra bytes in format specific field. bf.ReadBytes(chunkSize - 16); } else if (sfield == "LIST") { String listtype = bf.ReadString(4); // skip over LIST chunks which don't contain INFO subchunks if (listtype != "INFO") { bf.ReadBytes(chunkSize - 4); continue; } try { listbytecount = 4; #if DEBUG Console.WriteLine("------- INFO chunks: {0} bytes -------", chunkSize); #endif // iterate over all entries in LIST chunk while (listbytecount < chunkSize) { infofield = ""; infodescription = ""; infodata = ""; firstbyte = bf.ReadByte(); // if previous data had odd bytecount, was padded by null so skip if (firstbyte == 0) { listbytecount++; continue; } // if firstbyte is not an alpha char, read one more byte if (!Char.IsLetterOrDigit((char)firstbyte)) { firstbyte = bf.ReadByte(); listbytecount++; } // if we have a new chunk infofield += (char)firstbyte; for (int i = 1; i <= 3; i++) //get the remaining part of info chunk name ID { infofield += (char)bf.ReadByte(); } // get the info chunk data byte size infochunksize = bf.ReadInt32(); listbytecount += (8 + infochunksize); //Console.WriteLine("infofield: {0}, listbytecount: {1}, infochunksize: {2}", infofield, listbytecount, infochunksize); if (listbytecount > chunkSize) { bf.SetPosition(bf.GetPosition() - 8); break; } // get the info chunk data for (int i = 0; i < infochunksize; i++) { byteread = bf.ReadByte(); if (byteread == 0) // if null byte in string, ignore it { continue; } infodata += (char)byteread; } int unknownCount = 1; try { infodescription = (string)listinfo[infofield]; } catch (KeyNotFoundException) {} if (infodescription != null) { #if DEBUG Console.WriteLine("{0} ({1}) = {2}", infofield, infodescription, infodata); #endif InfoChunks.Add(infodescription, infodata); } else { #if DEBUG Console.WriteLine("unknown: {0} = {1}", infofield, infodata); #endif InfoChunks.Add(String.Format("unknown{0}", unknownCount), infodata); unknownCount++; } } //------- end iteration over LIST chunk ------------ } catch (Exception) {; // don't care about these? //Console.WriteLine("Error: {0}", e.ToString()); } #if DEBUG Console.WriteLine("------- end INFO chunks -------"); #endif } else { if (sfield.Equals("data")) { sampleCount = (int)dataSize / (wBitsPerSample / 8) / nChannels; soundData = new float[nChannels][]; for (int ic = 0; ic < nChannels; ic++) { soundData[ic] = new float[sampleCount]; } //********Data loading******** if (BitsPerSample == 8) { Read8Bit(bf, soundData, sampleCount, nChannels); } if (BitsPerSample == 16) { Read16Bit(bf, soundData, sampleCount, nChannels); } if (BitsPerSample == 32) { if (wFormatTag == WAVE_FORMAT_PCM) { Read32Bit(bf, soundData, sampleCount, nChannels); } else if (wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { Read32BitFloat(bf, soundData, sampleCount, nChannels); } } } else { // if NOT the fmt or LIST chunks skip data bf.ReadBytes(chunkSize); } } } // end while. //----------- End of chunk iteration ------------- if (isPCM && dataSize > 0) // compute duration of PCM wave file { long waveduration = 1000L * dataSize / bytespersec; // in msec units long mins = waveduration / 60000; // integer minutes double secs = 0.001 * (waveduration % 60000); //double secs. #if DEBUG Console.WriteLine("wav duration: {0} mins {1} sec", mins, secs); #endif } #if DEBUG Console.WriteLine("Final RIFF data bytecount: {0}", bytecount); #endif if ((8 + bytecount) != (int)fileLength) { Console.WriteLine("!!!!!!! Problem with file structure !!!!!!!!!"); return(false); } else { #if DEBUG Console.WriteLine("File chunk structure consistent with valid RIFF"); #endif } return(true); } catch (Exception e) { Console.WriteLine("Error: {0}", e.ToString()); return(false); } finally { // close all streams. bf.Close(); } }
public bool Process() { int bytespersec = 0; int byteread = 0; bool isPCM = false; Dictionary <string,string>listinfo = new Dictionary<string,string>(); for (int i=0; i<infotype.Length; i++) { listinfo.Add(infotype[i], infodesc[i]); } BinaryFile bf = new BinaryFile(selectedFile); try { FileInfo fileInfo = new FileInfo(selectedFile); fileLength = fileInfo.Length; int chunkSize=0, infochunksize=0, bytecount=0, listbytecount=0; string sfield="", infofield="", infodescription="", infodata=""; /* -------- Get RIFF chunk header --------- */ sfield = bf.ReadString(4); #if DEBUG Console.WriteLine("RIFF Header: {0}", sfield); #endif if (sfield != "RIFF") { Console.WriteLine(" **** Not a valid RIFF file ****"); return false; } // read RIFF data size chunkSize = bf.ReadInt32(); #if DEBUG Console.WriteLine("RIFF data size: {0}", chunkSize); #endif // read form-type (WAVE etc) sfield = bf.ReadString(4); #if DEBUG Console.WriteLine("Form-type: {0}", sfield); #endif riffDataSize = chunkSize; bytecount = 4; // initialize bytecount to include RIFF form-type bytes. while (bytecount < riffDataSize ) { // check for chunks inside RIFF data area. sfield=""; int firstbyte = bf.ReadByte() ; if (firstbyte == 0) { // if previous data had odd bytecount, was padded by null so skip bytecount++; continue; } sfield+= (char) firstbyte; // if we have a new chunk for (int i=1; i<=3; i++) { sfield += (char) bf.ReadByte() ; } chunkSize = 0; chunkSize = bf.ReadInt32(); bytecount += ( 8 + chunkSize ); #if DEBUG Console.WriteLine("{0} ----- data size: {1} bytes", sfield, chunkSize); #endif if (sfield == "data") { //get data size to compute duration later. dataSize = chunkSize; } if (sfield == "fmt ") { /* Offset Size Description Value 0x00 4 Chunk ID "fmt " (0x666D7420) 0x04 4 Chunk Data Size 16 + extra format bytes 0x08 2 Compression code 1 - 65,535 0x0a 2 Number of channels 1 - 65,535 0x0c 4 Sample rate 1 - 0xFFFFFFFF 0x10 4 Average bytes per second 1 - 0xFFFFFFFF 0x14 2 Block align 1 - 65,535 0x16 2 Significant bits per sample 2 - 65,535 0x18 2 Extra format bytes 0 - 65,535 0x1a Extra format bytes * */ // extract info from "format" chunk. if (chunkSize < 16) { Console.WriteLine(" **** Not a valid fmt chunk ****"); return false; } // Read compression code, 2 bytes wFormatTag = bf.ReadInt16(); if (wFormatTag == WAVE_FORMAT_PCM || wFormatTag == WAVE_FORMAT_EXTENSIBLE || wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { isPCM = true; } if (wFormatTag == WAVE_FORMAT_PCM) { #if DEBUG Console.WriteLine("\twFormatTag: WAVE_FORMAT_PCM") ; #endif } else if (wFormatTag == WAVE_FORMAT_EXTENSIBLE) { #if DEBUG Console.WriteLine("\twFormatTag: WAVE_FORMAT_EXTENSIBLE") ; #endif } else if (wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { #if DEBUG Console.WriteLine("\twFormatTag: WAVE_FORMAT_IEEE_FLOAT") ; #endif } else if (wFormatTag == WAVE_FORMAT_MPEGLAYER3) { #if DEBUG Console.WriteLine("\twFormatTag: WAVE_FORMAT_MPEGLAYER3") ; #endif } else { #if DEBUG Console.WriteLine("\twFormatTag: non-PCM format {0}", wFormatTag) ; #endif } // Read number of channels, 2 bytes nChannels = bf.ReadInt16(); #if DEBUG Console.WriteLine("\tnChannels: {0}", nChannels); #endif // Read sample rate, 4 bytes nSamplesPerSec = bf.ReadInt32(); #if DEBUG Console.WriteLine("\tnSamplesPerSec: {0}", nSamplesPerSec); #endif // Read average bytes per second, 4 bytes nAvgBytesPerSec = bf.ReadInt32(); bytespersec = nAvgBytesPerSec; #if DEBUG Console.WriteLine("\tnAvgBytesPerSec: {0}", nAvgBytesPerSec); #endif // Read block align, 2 bytes nBlockAlign = bf.ReadInt16(); #if DEBUG Console.WriteLine("\tnBlockAlign: {0}", nBlockAlign); #endif // Read significant bits per sample, 2 bytes if (isPCM) { // if PCM or EXTENSIBLE format wBitsPerSample = bf.ReadInt16(); #if DEBUG Console.WriteLine("\twBitsPerSample: {0}", wBitsPerSample); #endif } else { bf.ReadBytes(2); wBitsPerSample = 0; } //skip over any extra bytes in format specific field. bf.ReadBytes(chunkSize - 16); } else if (sfield == "LIST") { String listtype = bf.ReadString(4); // skip over LIST chunks which don't contain INFO subchunks if (listtype != "INFO") { bf.ReadBytes(chunkSize - 4); continue; } try { listbytecount = 4; #if DEBUG Console.WriteLine("------- INFO chunks: {0} bytes -------", chunkSize); #endif // iterate over all entries in LIST chunk while (listbytecount < chunkSize) { infofield = ""; infodescription = ""; infodata = ""; firstbyte = bf.ReadByte(); // if previous data had odd bytecount, was padded by null so skip if (firstbyte == 0) { listbytecount++; continue; } // if firstbyte is not an alpha char, read one more byte if (!Char.IsLetterOrDigit( (char) firstbyte )) { firstbyte = bf.ReadByte(); listbytecount++; } // if we have a new chunk infofield += (char) firstbyte; for (int i=1; i<=3; i++) { //get the remaining part of info chunk name ID infofield += (char) bf.ReadByte() ; } // get the info chunk data byte size infochunksize = bf.ReadInt32(); listbytecount += ( 8 + infochunksize ); //Console.WriteLine("infofield: {0}, listbytecount: {1}, infochunksize: {2}", infofield, listbytecount, infochunksize); if (listbytecount > chunkSize) { bf.SetPosition(bf.GetPosition() - 8); break; } // get the info chunk data for (int i=0; i < infochunksize; i++) { byteread = bf.ReadByte(); if (byteread == 0) { // if null byte in string, ignore it continue; } infodata += (char) byteread; } int unknownCount = 1; try { infodescription = (string) listinfo[infofield]; } catch (KeyNotFoundException) {} if (infodescription != null) { #if DEBUG Console.WriteLine("{0} ({1}) = {2}", infofield, infodescription, infodata); #endif InfoChunks.Add(infodescription, infodata); } else { #if DEBUG Console.WriteLine("unknown: {0} = {1}", infofield, infodata); #endif InfoChunks.Add(String.Format("unknown{0}", unknownCount), infodata); unknownCount++; } } //------- end iteration over LIST chunk ------------ } catch (Exception) {; // don't care about these? //Console.WriteLine("Error: {0}", e.ToString()); } #if DEBUG Console.WriteLine("------- end INFO chunks -------"); #endif } else { if (sfield.Equals("data")) { sampleCount = (int) dataSize / (wBitsPerSample / 8) / nChannels; soundData = new float[nChannels][]; for (int ic = 0; ic < nChannels; ic++) { soundData[ic] = new float[sampleCount]; } //********Data loading******** if (BitsPerSample == 8) { Read8Bit(bf, soundData, sampleCount, nChannels); } if (BitsPerSample == 16) { Read16Bit(bf, soundData, sampleCount, nChannels); } if (BitsPerSample == 32) { if (wFormatTag == WAVE_FORMAT_PCM) { Read32Bit(bf, soundData, sampleCount, nChannels); } else if (wFormatTag == WAVE_FORMAT_IEEE_FLOAT) { Read32BitFloat(bf, soundData, sampleCount, nChannels); } } } else { // if NOT the fmt or LIST chunks skip data bf.ReadBytes(chunkSize); } } } // end while. //----------- End of chunk iteration ------------- if(isPCM && dataSize > 0) { // compute duration of PCM wave file long waveduration = 1000L * dataSize / bytespersec; // in msec units long mins = waveduration / 60000; // integer minutes double secs = 0.001 * (waveduration % 60000); //double secs. #if DEBUG Console.WriteLine("wav duration: {0} mins {1} sec", mins, secs); #endif } #if DEBUG Console.WriteLine("Final RIFF data bytecount: {0}", bytecount); #endif if ( ( 8 + bytecount) != (int) fileLength) { Console.WriteLine("!!!!!!! Problem with file structure !!!!!!!!!"); return false; } else { #if DEBUG Console.WriteLine("File chunk structure consistent with valid RIFF") ; #endif } return true; } catch (Exception e) { Console.WriteLine("Error: {0}", e.ToString()) ; return false; } finally { // close all streams. bf.Close(); } }