예제 #1
0
파일: WAVPlay.cs 프로젝트: BrettJohn/TabCat
        /// =======================================================================================================
        public static string WavPlay(string wav_path, string form_alias = "")
        {
            CAT.InteractiveAddNamedOverlay("WAVPLAY", "Preparing for play of " + wav_path);
            string   returnvalue = "";
            string   path        = API.DISK.AutoAddBaseDirectory(API.DISK.AutoAddExt(wav_path, ".wav"));
            DateTime starttime   = DateTime.Now;

            if (!File.Exists(path))
            {
                string err = "Error: Could not find file '" + path + "'";
                CAT.InteractiveUpdateNamedOverlay("WAVPLAY", err, CAT.Status.FAIL);
                return(err);
            }
            string name = "p" + CircularBufer;

            CircularBufer++;
            mciSendString("open " + path + " type waveaudio alias " + name, null, 0, 0);
            mciSendString("play " + name, null, 0, 0);
            returnvalue += "Load time is " + (DateTime.Now - starttime).TotalMilliseconds + "ms. ";
            mciSendString("play " + name + " notify", null, 0, 0);
            StringBuilder sb = new StringBuilder(128);

            mciSendString("status " + name + " length", sb, 128, 0);
            string newsb      = sb.ToString();
            ulong  songlength = Convert.ToUInt64(sb.ToString());

            CAT.FormAccess(CAT.FormDelegates.SetLength, new object[] { songlength }, form_alias);
            returnvalue += "Length is " + songlength + "ms. ";
            ulong position = 0;

            while (!CAT.AbortAll && !CAT.AbortCurrent && position < songlength)
            {
                Thread.Sleep(1); // 1 ms resolution - frees up CPU
                mciSendString("status " + name + " position", sb, 128, 0);
                newsb    = sb.ToString();
                position = Convert.ToUInt64(sb.ToString());
                CAT.InteractiveUpdateNamedOverlay("WAVPLAY", "Playing " + path + " " + position + @"/" + songlength + "ms", CAT.Status.BUSY);
                if (SetPos)
                {
                    SetPos = false;
                    double pos = (double)CAT.FormAccess(CAT.FormDelegates.GetPosTrackBar, null, form_alias) * songlength;
                    mciSendString("seek " + name + " to " + (int)(pos), null, 0, 0);
                    mciSendString("play " + name + " notify", null, 0, 0);
                }
                else
                {
                    CAT.FormAccess(CAT.FormDelegates.SetPosTrackBar, new object[] { ((double)position / songlength) }, form_alias);
                }
                if (Restarter)
                {
                    Restarter = false;
                    mciSendString("seek " + name + " to start", sb, 128, 0);
                    mciSendString("play " + name + " notify", null, 0, 0);
                }
            }
            mciSendString("close " + name, null, 0, 0);
            return(returnvalue);
        }
예제 #2
0
파일: BUILD.cs 프로젝트: BrettJohn/TabCat
        /// =======================================================================================================
        public static Return BUILD(string source_path, string timebase_ms, string resolution, string output_folder)
        {
            CAT.InteractiveAddNamedOverlay("WAVBUILD", "Preparing for build of " + source_path);
            string sourcepath = DISK.AutoAddExt(source_path, ".txt");

            string[]  sourcelines    = File.ReadAllLines(DISK.AutoAddBaseDirectory(sourcepath));
            DateTime  starttime      = DateTime.Now;
            WAVFormat masterfmt      = new WAVFormat(2, 96000, 3); // Ideal format
            double    timebase       = string.IsNullOrWhiteSpace(timebase_ms) ? 250 : Convert.ToDouble(timebase_ms);
            int       res            = string.IsNullOrWhiteSpace(resolution) ? 32 : Convert.ToInt16(resolution);
            int       totaltimems    = res == 1 ? Convert.ToInt32(timebase * res) : Convert.ToInt32(timebase * res) + 5000; // 5 seconds decay
            uint      masterdatasize = ConvertMsToNumberOfBytes(Convert.ToUInt32(totaltimems), masterfmt);

            byte[] masteralldata     = CreateBlankWave(Convert.ToUInt32(totaltimems), masterfmt);
            int    masterstartofdata = GetStartOfDataIndex(masteralldata);
            uint   masterlocation    = 0;
            int    rowcount          = 0;
            int    rowmax            = sourcelines.Length / 2;

            CAT.InteractiveUpdateNamedOverlay("WAVBUILD", "Starting build of " + source_path);
            for (int linenumber = 0; linenumber < sourcelines.Length - 1; linenumber += 2)
            {
                rowcount++;
                string files;
                byte[] newalldata;
                double volumeleft  = 1.0;
                double volumeright = 1.0;
                if (sourcelines[linenumber].Contains("\t"))
                {
                    files = sourcelines[linenumber].Split('\t')[0];
                    try
                    {
                        string volstring = sourcelines[linenumber].Split('\t')[1];
                        if (volstring.Contains(";"))
                        {
                            volumeleft  = Convert.ToDouble(volstring.Split(';')[0]);
                            volumeright = Convert.ToDouble(volstring.Split(';')[1]);
                        }
                        else if (volstring.Contains(":"))
                        {
                            volumeleft  = Convert.ToDouble(volstring.Split(':')[0]);
                            volumeright = Convert.ToDouble(volstring.Split(':')[1]);
                        }
                        else
                        {
                            volumeleft  = Convert.ToDouble(volstring);
                            volumeright = Convert.ToDouble(volstring);
                        }
                    } catch { /* use default */ }
                }
                else
                {
                    files = sourcelines[linenumber];
                }
                int filecount = 0;
                foreach (string filename in files.Split(';'))
                {
                    filecount++;
                    string updatedfilename = filename;
                    if (!filename.Contains(".wav"))
                    {
                        updatedfilename = filename + ".wav";
                    }                                                              // Auto add extension
                    if (!File.Exists(updatedfilename))
                    {
                        updatedfilename = output_folder + @"\" + updatedfilename;
                    }                                                                                      // auto add output folder
                    if (File.Exists(updatedfilename))
                    {
                        newalldata = File.ReadAllBytes(updatedfilename);
                        WAVFormat newfmt         = ReadFormat(newalldata);
                        int       newstartofdata = GetStartOfDataIndex(newalldata);
                        int       newdatasize    = newalldata.Length - newstartofdata;
                        byte[]    newdata        = new byte[newdatasize];
                        Array.Copy(newalldata, newstartofdata, newdata, 0, newdatasize); // copy data - only data is used from new file (header is discarded)
                        string argument = sourcelines[linenumber + 1];
                        if (!string.IsNullOrWhiteSpace(argument))
                        {
                            string[] arguments     = argument.Split(',');
                            int      locationcount = 0;
                            foreach (string location in arguments)
                            {
                                locationcount++;
                                uint locationtouse = Convert.ToUInt32(Convert.ToDouble(location));
                                if (location.Contains("+"))
                                {
                                    masterlocation += locationtouse;
                                }
                                else
                                {
                                    masterlocation = locationtouse;
                                }
                                string currentbuilditem = " (row:" + rowcount + @"/" + rowmax +
                                                          " file:" + filecount + @"/" + files.Split(';').Length +
                                                          " location:" + locationcount + @"/" + arguments.Length + ")";
                                CAT.InteractiveUpdateNamedOverlay("WAVBUILD", source_path + ": Adding " + updatedfilename + " at " + masterlocation + currentbuilditem, API.CAT.Status.PASS);
                                uint masteroffset = ConvertMsToNumberOfBytes(masterlocation, masterfmt);
                                bool isleft       = true;

                                // Scroll through each of the new data indeces
                                for (int newindex = 0; newindex < newdatasize - (int)newfmt.ByteDepth; newindex += (int)(newfmt.NumberOfChannels * newfmt.ByteDepth))
                                {
                                    double masterkhz   = ((ulong)masterfmt.ByteDepth * (ulong)masterfmt.NumberOfChannels * (ulong)masterfmt.SampleRate) / 1000.0;
                                    double newkhz      = ((ulong)newfmt.ByteDepth * (ulong)newfmt.NumberOfChannels * (ulong)newfmt.SampleRate) / 1000.0;
                                    double ratio       = masterkhz / newkhz;
                                    int    masterindex = (int)(newindex * ratio);
                                    if (masterindex + masteroffset < masterdatasize)
                                    {
                                        // Scroll to (left channel) sample start byte
                                        while ((masterindex + masteroffset) % (masterfmt.NumberOfChannels * masterfmt.ByteDepth) != 0)
                                        {
                                            masterindex--;
                                        }

                                        for (int i = 0; i < newfmt.NumberOfChannels; i++)
                                        {
                                            for (int j = 0; j < (int)Math.Ceiling((double)(masterfmt.SampleRate / newfmt.SampleRate)); j++) // Fill in gaps
                                            {
                                                int    mastersamplelocation = masterstartofdata + (int)masteroffset + masterindex + i * (int)masterfmt.ByteDepth + j * ((int)masterfmt.NumberOfChannels * (int)masterfmt.ByteDepth);
                                                int    mastersample         = Deserialise(masteralldata, mastersamplelocation, (int)masterfmt.ByteDepth);
                                                int    newsample            = Deserialise(newdata, newindex + i * (int)newfmt.ByteDepth, (int)newfmt.ByteDepth);
                                                double masternorm           = Normalise(mastersample, (int)masterfmt.ByteDepth);
                                                double volume = isleft ? volumeleft : volumeright;
                                                isleft = !isleft;
                                                double combined = (masternorm + volume * Normalise(newsample, (int)newfmt.ByteDepth));

                                                // Limiting proved highly effective
                                                if (combined > 0.499999)
                                                {
                                                    combined = 0.499999;
                                                    // returndata += "Clip (positive) detected at " + ConvertNumberOfBytesToMs((uint)j, newfmt);
                                                }
                                                if (combined < -0.499999)
                                                {
                                                    combined = -0.499999;
                                                    // returndata += "Clip (negative) detected at " + ConvertNumberOfBytesToMs((uint)j, newfmt);
                                                }

                                                Serialise(ref masteralldata, mastersamplelocation, Denormalise(combined, (int)masterfmt.ByteDepth), (int)masterfmt.ByteDepth);

                                                // Copy to both channels
                                                if (newfmt.NumberOfChannels == 1)
                                                {
                                                    Serialise(ref masteralldata, masterstartofdata + (int)masteroffset + masterindex + (int)masterfmt.ByteDepth, Denormalise(combined, (int)masterfmt.ByteDepth), (int)masterfmt.ByteDepth);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            CAT.InteractiveAddOverlay(updatedfilename + " ignored - no times specified", API.CAT.Status.WARN);
                        }
                    }
                    else
                    {
                        CAT.InteractiveAddOverlay(updatedfilename + " does not exist... continued", API.CAT.Status.FAIL);
                    }
                }
            }
            if (!Directory.Exists(output_folder))
            {
                Directory.CreateDirectory(output_folder);
                CAT.InteractiveAddOverlay("Created " + output_folder + " directory", API.CAT.Status.WARN);
            }
            try
            {
                string outputfilename = output_folder + "\\" + Path.GetFileNameWithoutExtension(sourcepath) + ".wav";
                File.WriteAllBytes(outputfilename, masteralldata);
                CAT.InteractiveAddOverlay("Built " + outputfilename, API.CAT.Status.PASS);
                CAT.InteractiveAddOverlay("Build time " + (DateTime.Now - starttime).TotalMilliseconds + "ms", API.CAT.Status.INFO);
            }
            catch (Exception e) { CAT.InteractiveAddOverlay("Failed build:\r\n" + API.CAT.ErrorMsg(e), API.CAT.Status.FAIL); }

            return(new Return("Done"));
        }