public bool ConvertToWAV(string inPath, string outPath, uint sampleRate, uint sampleSize, uint channels) { WaveLib.WaveFormat fmt = new WaveLib.WaveFormat((int)sampleRate, (int)sampleSize, (int)channels); using (WmaStream str = new WmaStream(inPath, fmt)) { byte[] buffer = new byte[str.SampleSize * 2]; AudioWriter writer = new WaveWriter(new FileStream(outPath, FileMode.Create), str.Format); try { int read; while ((read = str.Read(buffer, 0, buffer.Length)) > 0) { writer.Write(buffer, 0, read); } } finally { writer.Close(); } } //str.Close() is automatically called by Dispose. return(true); }
private void WMDataFill() { //int bufferwriteoffset = 0; using (WmaStream str = new WmaStream(file)) { byte[] buffer = new byte[131072]; int firstread = str.Read(buffer, 0, buffer.Length); sound.Write(0, buffer, LockFlag.None); //firstread = str.Read(buffer, 0, buffer.Length); //sound.Write(131072, buffer, LockFlag.None); try { int count = 0; int read; while ((read = str.Read(buffer, 0, buffer.Length)) > 0) { BufferNotificationEvent.WaitOne(); if (sound.PlayPosition < 131071) { sound.Write(131072, buffer, LockFlag.None); } else { sound.Write(0, buffer, LockFlag.None); } count++; } } finally { str.Close(); str.Dispose(); } BufferNotificationEvent.WaitOne(); End(); } }
public static void FileEncode(SortableBindingList <FileEntryClass> workinglist, string m4boutputfile, int TargetRate, int Quant, int usetns, ProgressUpdate procprogress, AudioBookConverterMain _owner) { Owner = _owner; long inputsamples = 0; long maxbytes = 0; ulong filesamples = 0; ulong totalms = 0; ulong filems; int read; int fileindex = 0; int lastupdate = 0; bool havechapters = false; int bufferfactor = 256; //scan the files, see if we need chapter processing foreach (FileEntryClass listitem in workinglist) { if (listitem.Chapter) { havechapters = true; if (listitem.ChapterTitle == null) { if (listitem.Title != null) { listitem.ChapterTitle = listitem.Title; } else { listitem.ChapterTitle = Path.GetFileNameWithoutExtension(listitem.FilePath); } } } } WmaStream wavfile = new WmaStream(workinglist[fileindex].FilePath); uint samplerate = (uint)wavfile.Format.nSamplesPerSec; uint numchannels = (uint)wavfile.Format.nChannels; string tempfile = Path.GetTempFileName(); //FileStream outputfile = new FileStream(tempfile, FileMode.Create); Bento4Writer mp4writer = new Bento4Writer(m4boutputfile, tempfile); // Faac Settings faac encoder = new faac(samplerate, numchannels); inputsamples = encoder.InputSamples; maxbytes = encoder.MaxBytes; encoder.QuantQual = Quant; encoder.InputFormat = 1; //encoder.BandWidth = 8000;// (int)samplerate / 6; encoder.UseTNS = usetns; encoder.UseLFE = 0; encoder.BitRate = TargetRate * 1000; byte[] decoderspecific = encoder.DecoderSpecInfo; string[] chaptitles = new string[255]; ulong[] chapstart = new ulong[255]; uint totalchapters = 0; if (havechapters) { chapstart[0] = 0; totalchapters = 0; if (!workinglist[fileindex].Chapter) { chaptitles[0] = "Begin"; } else { chaptitles[0] = workinglist[fileindex].ChapterTitleResolver; } } procprogress.TotalFiles = workinglist.Count; procprogress.TotalKbytes = (int)wavfile.Length / 1024; procprogress.CurrentFile = fileindex + 1; procprogress.CurrentFilename = workinglist[fileindex].FilePath; read = 0; //setup buffer for data coming from faac byte[] aac_buffer = new byte[maxbytes * bufferfactor]; int aac_buffer_offset = 0; int aac_buffer_frames = 0; //DateTime start = DateTime.Now; while (fileindex < workinglist.Count && read != -1) { if (Owner.bgAACEncoder.CancellationPending) { wavfile.Close(); //outputfile.Close(); //System.IO.File.Delete(tempfile); return; } short[] isamples = new short[inputsamples]; byte[] wavbytes = new byte[inputsamples * 2]; int bytes = 0; //read from source file bytes = wavfile.Read(wavbytes, 0, (int)inputsamples * 2); //update filesamples with number of samples filesamples += (ulong)bytes / (numchannels * 2); if (wavfile.Position >= wavfile.Length || bytes < inputsamples * 2) { filems = filesamples * 1000 / samplerate; workinglist[fileindex].Duration = TimeSpan.FromMilliseconds(filems); //if that file we just ran was flagged as a chapter start, finalize the last and create a new if (workinglist[fileindex].Chapter && fileindex != 0) { chapstart[totalchapters] = totalms; totalchapters++; chaptitles[totalchapters] = workinglist[fileindex].ChapterTitleResolver; } //accumulate the total millisecond counter totalms += filems; fileindex++; //out of data, move to next file wavfile.Close(); if (fileindex < workinglist.Count) { wavfile = new WmaStream(workinglist[fileindex].FilePath); //need to read more to get required number of input samples if (bytes < inputsamples * 2) { int requiredbytes = (int)(inputsamples * 2) - bytes; byte[] extrawavbytes = new byte[requiredbytes]; int extrabytes; extrabytes = wavfile.Read(extrawavbytes, 0, requiredbytes); Array.Copy(extrawavbytes, 0, wavbytes, bytes, extrabytes); bytes += extrabytes; filesamples = (ulong)extrabytes / (numchannels * 2); } else { filesamples = 0; } procprogress.CurrentFile = fileindex + 1; procprogress.CurrentKbyte = 1; procprogress.TotalKbytes = (int)wavfile.Length / 1024; procprogress.CurrentFilename = workinglist[fileindex].FilePath; Owner.bgAACEncoder.ReportProgress(0, procprogress); lastupdate = 0; } } //Notification to user front-end if (lastupdate > 200) { if (bytes == inputsamples * 2) { procprogress.CurrentKbyte = (int)wavfile.Position / 1024; } else { procprogress.CurrentKbyte = procprogress.TotalKbytes; } lastupdate = 0; Owner.bgAACEncoder.ReportProgress(0, procprogress); } lastupdate++; //convert the byte[] into a short[] int z = 0; for (int x = 0; x < bytes; x += 2) { isamples[z] = (short)((wavbytes[x + 1] << 8) | wavbytes[x] << 0); z++; } byte[] output = new byte[maxbytes]; uint buffersize = 0; int inputsam = isamples.Length; //feed the samples to the aac encoder read = encoder.Encode(isamples, inputsam, out output, out buffersize); //if the encoder encoded, write it out to the aac buffer if (read > 0) { Array.Copy(output, 0, aac_buffer, aac_buffer_offset, read); aac_buffer_offset += read; aac_buffer_frames++; //if the buffer is full, write it out to bento if (aac_buffer_frames == bufferfactor) { mp4writer.Write(aac_buffer, aac_buffer_frames); aac_buffer_frames = 0; aac_buffer_offset = 0; } } } //end sample processing loop //flush the sample_buffer if (aac_buffer_frames > 0) { mp4writer.Write(aac_buffer, aac_buffer_frames); } encoder.Close(); encoder.Dispose(); wavfile.Close(); wavfile.Dispose(); if (havechapters) { chapstart[totalchapters] = totalms; totalchapters++; mp4writer.WriteChapters(chaptitles, chapstart, totalchapters); } ////fake chapter data //for (int fx = 0; fx < 35; fx++) { // chaptitles[fx] = "Chapter " + fx; // chapstart[fx] = (ulong)((2500 * fx) + fx); //} //totalchapters = 35; if (Owner.bgAACEncoder.CancellationPending) { return; } procprogress.CurrentFilename = "Packaging Mpeg4 Audiobook File"; procprogress.TotalFiles = 1; procprogress.CurrentFile = 1; procprogress.BentoWorking = true; Owner.bgAACEncoder.ReportProgress(0, procprogress); //tempfile = "c:\\mp4utils\\file.aac"; //chapdata = "c:\\mp4utils\\chapdata.txt"; //BentoSharp.Bento4 BentoClass = new Bento4(); //int bentoerror = BentoClass.aac2mp4(tempfile, m4boutputfile, decoderspecific, chapdata, chapstart, totalchapters); //bentoerror = BentoClass.mp4chapter("c:\\mp4utils\\bentoout.m4b","c:\\mp4utils\\chapout.m4b",chapdata,chaptimes,totalchapters); //BentoClass = null; mp4writer.Save(); //System.IO.File.Delete(tempfile); //System.IO.File.Delete(chapdata); mp4writer.Dispose(); }
public PlayerClass(AudioBookConverterMain Caller, string filename) { if (GetSourceExt(filename) != "mp3") { return; } file = filename; Parent = Caller; Microsoft.DirectX.DirectSound.WaveFormat format = new Microsoft.DirectX.DirectSound.WaveFormat(); WmaStream wmastr = new WmaStream(filename); format.BlockAlign = wmastr.Format.nBlockAlign; format.Channels = wmastr.Format.nChannels; format.SamplesPerSecond = wmastr.Format.nSamplesPerSec; format.BitsPerSample = wmastr.Format.wBitsPerSample; format.AverageBytesPerSecond = format.BlockAlign * format.SamplesPerSecond; wmastr.Dispose(); BufferDescription desc = new BufferDescription(format); desc.ControlPan = true; desc.GlobalFocus = true; desc.BufferBytes = 262144; desc.ControlPositionNotify = true; desc.CanGetCurrentPosition = true; desc.ControlVolume = true; desc.StickyFocus = true; desc.LocateInSoftware = true; desc.ControlEffects = false; desc.LocateInHardware = false; desc.Control3D = false; //MemoryStream bufferstream = new MemoryStream(262144); Device device = new Device(); device.SetCooperativeLevel(Parent, CooperativeLevel.Priority); sound = new SecondaryBuffer(desc, device); sound.SetCurrentPosition(1); sound.Volume = 0; sound.Pan = 0; BufferNotificationEvent = new AutoResetEvent(false); BufferNotify = new Notify(sound); BufferPositionNotify[] BufferPositions = new BufferPositionNotify[2]; BufferPositions[0].Offset = 0; BufferPositions[0].EventNotifyHandle = BufferNotificationEvent.Handle; BufferPositions[1].Offset = (desc.BufferBytes / 2); BufferPositions[1].EventNotifyHandle = BufferNotificationEvent.Handle; BufferNotify.SetNotificationPositions(BufferPositions); DataTransferThread = new Thread(new ThreadStart(WMDataFill)); //if (GetSourceExt(filename) =="mp4") DataTransferThread = new Thread(new ThreadStart(FaadDataFill)); //if (GetSourceExt(filename) =="flac") DataTransferThread = new Thread(new ThreadStart(FlacDataFill)); //if (GetSourceExt(filename) =="ogg") DataTransferThread = new Thread(new ThreadStart(OggDataFill)); DataTransferThread.Name = "BufferFill"; DataTransferThread.Priority = ThreadPriority.Highest; DataTransferThread.Start(); }
static void Main(string[] args) { uint samplerate = 44100; uint numchannels = 2; long inputsamples = 0; long maxbytes = 0; string file = "c:\\sandbox\\testfile.mp3"; WmaStream wavfile = new WmaStream(file); samplerate = (uint)wavfile.Format.nSamplesPerSec; FileStream outputfile = new FileStream("c:\\mp4utils\\faactest.aac", FileMode.Create); faac encoder = new faac(samplerate, 2); inputsamples = encoder.InputSamples; maxbytes = encoder.MaxBytes; encoder.BitRate = 16000; encoder.InputFormat = 1; encoder.BandWidth = 22050; encoder.UseTNS = 0; int read = 0; uint decoderspeclength = 0; byte[] decoderspecificinfo = encoder.DecoderSpecInfo; DateTime start = DateTime.Now; long totalsamples = 0; while (wavfile.Position < wavfile.Length && read != -1) { short[] isamples = new short[inputsamples]; byte[] wavbytes = new byte[inputsamples * 2]; int bytes = 0; if (wavfile.Position < wavfile.Length) { bytes = wavfile.Read(wavbytes, 0, (int)inputsamples * 2); } int z = 0; for (int x = 0; x < bytes; x += 2) { isamples[z] = (short)((wavbytes[x + 1] << 8) | wavbytes[x] << 0); z++; } byte[] output = new byte[maxbytes]; uint buffersize = 0; int inputsam = (int)inputsamples; read = encoder.Encode(isamples, inputsam, out output, out buffersize); outputfile.Write(output, 0, (int)read); totalsamples += bytes / 2; } Console.WriteLine(DateTime.Now - start); Console.WriteLine("Audio Duration: " + TimeSpan.FromSeconds((totalsamples / samplerate) / numchannels)); outputfile.Close(); }