Beispiel #1
0
 /// <summary>
 /// 语音唤醒
 /// </summary>
 public static void VoiceWakeUp()
 {
     try
     {
         int retCode = MSC.MSPLogin(null, null, msp_login.APPID + ",engine_start = ivw,ivw_res_path =fo|res/ivw/wakeupresource.jet,work_dir = .");
         if (retCode != (int)ErrorCode.MSP_SUCCESS)
         {
             Debug.Log("登陆失败!"); return;
         }
         Debug.Log(string.Format("{0} 登陆成功,正在开启引擎..", DateTime.Now.Ticks));
         sid = Utils.Ptr2Str(MSC.QIVWSessionBegin(string.Empty, "sst=wakeup,ivw_threshold=0:-20", ref retCode));
         if (retCode != (int)ErrorCode.MSP_SUCCESS)
         {
             Debug.Log("开启失败!"); return;
         }
         Debug.Log(string.Format("{1} 开启成功[{0}],正在注册..", sid, DateTime.Now.Ticks));
         retCode = MSC.QIVWRegisterNotify(sid, registerCallback, new IntPtr());
         if (retCode != (int)ErrorCode.MSP_SUCCESS)
         {
             Debug.Log("注册失败!"); return;
         }
         Debug.Log(string.Format("{1} 注册成功,语音唤醒[{0}]正在初始化...", sid, DateTime.Now.Ticks));
         VoiceArousal(sid);
         MSC.QIVWSessionEnd(sid, string.Empty);
     }
     finally
     {
         MSC.MSPLogout();
     }
 }
Beispiel #2
0
    public static int MSCLogin()
    {
        string login_configs = msp_login.APPID + ", work_dir = .";     //登录参数,自己注册后获取的appid

        ret = MSC.MSPLogin(string.Empty, string.Empty, login_configs); //第一个参数为用户名,第二个参数为密码,第三个参数是登录参数,用户名和密码需要在http://open.voicecloud.cn
        return(ret);
    }
Beispiel #3
0
    public static void StopSpeech()
    {
        Debug.Log("停止");
        int ret = MSC.QISRSessionEnd(sid, string.Empty);

        nar.StopRec();
        mt.isFinished = true;
    }
Beispiel #4
0
    /// <summary>
    /// 单次语音识别方法
    /// </summary>
    /// <param name="sid"></param>
    /// <returns></returns>
    private static RecogStatus SingleSpeechRecognition(string ssid)
    {
        rec_result = "";
        byte[] audio_buffer = Utils.GetFileData(mt.voice_path + "/rec.wav");
        long   audio_size   = audio_buffer.Length;
        long   audio_count  = 0;

        ep_status = epStatus.MSP_EP_LOOKING_FOR_SPEECH;
        while (epStatus.MSP_EP_AFTER_SPEECH != ep_status)
        {
            audio_stat = audioStatus.MSP_AUDIO_SAMPLE_CONTINUE;
            long len = 10 * FRAME_LEN; //16k音频,10帧 (时长200ms)
            if (audio_size < 2 * len)
            {
                len = (int)audio_size;
            }
            if (len <= 0)
            {
                break;
            }
            if (0 == audio_count)
            {
                audio_stat = audioStatus.MSP_AUDIO_SAMPLE_FIRST;
            }
            ret = MSC.QISRAudioWrite(ssid, audio_buffer.Skip((int)audio_count).Take((int)len).ToArray(), (uint)len, audio_stat, ref ep_status, ref recoStatus);
            if (ret != (int)ErrorCode.MSP_SUCCESS)
            {
                Debug.Log(string.Format("读取音频失败:{0}!", ret)); return(RecogStatus.ISR_REC_NULL);
            }
            audio_count += len;
            audio_size  -= len;
        }
        ret = MSC.QISRAudioWrite(ssid, null, 0, audioStatus.MSP_AUDIO_SAMPLE_LAST, ref ep_status, ref recoStatus);
        if (ret != (int)ErrorCode.MSP_SUCCESS)
        {
            Debug.Log(string.Format("识别音频失败:{0}!", ret)); return(RecogStatus.ISR_REC_NULL);
        }
        while (RecogStatus.ISR_REC_STATUS_SPEECH_COMPLETE != recoStatus)
        {
            IntPtr rslt = MSC.QISRGetResult(ssid, ref recoStatus, 0, ref ret);
            if (ret != (int)ErrorCode.MSP_SUCCESS)
            {
                Debug.Log(string.Format("音频无法识别:{0}!", ret)); return(RecogStatus.ISR_REC_NULL);
            }

            if (rslt != IntPtr.Zero)
            {
                rec_result = rec_result + Utils.Ptr2Str(rslt);
                if (rec_result.Length >= BUFFER_SIZE)
                {
                    Debug.Log("no enough buffer for rec_result");
                    return(RecogStatus.ISR_REC_NULL);
                }
            }
            Thread.Sleep(150); //防止频繁占用CPU
        }
        return(recoStatus);
    }
Beispiel #5
0
    /// <summary>
    /// 构建语法网络
    /// </summary>
    int GrammarBuild(string grm_type, string file)
    {
        string @params = "engine_type=local,asr_res_path=fo|res/asr/common.jet, sample_rate=16000, grm_build_path=res/asr/GrmBuilld";
        //string @params = "engine_type=cloud,sample_rate=16000";
        string       grm_content = File.ReadAllText(@"call.bnf", Encoding.Default);
        uint         grm_cnt_len = (uint)System.Text.Encoding.Default.GetBytes(grm_content).Length;
        QISRUserData userdata    = getUserData();

        Debug.Log(grm_content);
        return(MSC.QISRBuildGrammar(grm_type, grm_content, grm_cnt_len, @params, grammarCallBack, ref userdata));
    }
Beispiel #6
0
    public bool FlowStart = false;   //流程开始标识

    // Use this for initialization
    void Start()
    {
        if (VoiceManage.MSCLogin() != (int)ErrorCode.MSP_SUCCESS)
        {
            Debug.Log("登陆失败!" + ret); MSC.MSPLogout(); return;
        }
        mc = new M1101Ctrl();
        mc.mResultAction = FlowStartAction;
        u             = Camera.main.GetComponent <UIObject>();
        BeforeAskList = Answer.LoadQuestions(2, 1);
        AfterAskList  = Answer.LoadQuestions(2, 2);
        AnswerList    = Answer.LoadQuestions(1, 1);
        init();
    }
Beispiel #7
0
 /// <summary>
 /// 合成语音
 /// </summary>
 /// <param name="text">语音内容</param>
 /// <param name="name">文件名</param>
 /// <param name="path">音频存放地址</param>
 public SynthStatus PlayVoice(string text, string name, string path)
 {
     try
     {
         //string @params = "engine_type = cloud,voice_name=xiaofeng,speed=50,volume=50,pitch=50,text_encoding =UTF8,background_sound=0,sample_rate=16000,rdn=1";
         string @params = "engine_type = local,voice_name=xiaofeng, text_encoding = UTF8, tts_res_path = fo|res\\tts\\xiaofeng.jet;fo|res\\tts\\common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 1";
         sid = Utils.Ptr2Str(MSC.QTTSSessionBegin(@params, ref ret));
         Debug.Log(string.Format("-->开启一次语音合成[{0}]", sid));
         return(SpeechSynthesis(sid, text, name, path));
     }
     finally
     {
         MSC.QTTSSessionEnd(sid, string.Empty);
     }
 }
Beispiel #8
0
    /// <summary>
    /// 语音合成
    /// </summary>
    /// <param name="sid"></param>
    /// <returns></returns>
    private SynthStatus SpeechSynthesis(string sid, string text, string name, string path)
    {
        string filename        = name + ".wav"; //合成的语音文件
        uint   audio_len       = 0;
        uint   audio_total_len = 0;

        synth_status = SynthStatus.MSP_TTS_FLAG_STILL_HAVE_DATA;
        ret          = MSC.QTTSTextPut(sid, text, (uint)Encoding.UTF8.GetByteCount(text), string.Empty);
        if (ret != (int)ErrorCode.MSP_SUCCESS)
        {
            Debug.Log("写入文本失败!" + ret); return(synth_status);
        }
        MemoryStream memoryStream = new MemoryStream();

        while (synth_status != SynthStatus.MSP_TTS_FLAG_DATA_END)
        {
            IntPtr source = MSC.QTTSAudioGet(sid, ref audio_len, ref synth_status, ref ret);
            if (ret != (int)ErrorCode.MSP_SUCCESS)
            {
                Debug.Log("合成失败!" + ret); return(synth_status);
            }
            byte[] array = new byte[(int)audio_len];
            if (audio_len > 0)
            {
                Marshal.Copy(source, array, 0, (int)audio_len);
                memoryStream.Write(array, 0, array.Length);
                audio_total_len = audio_total_len + audio_len;
            }
            Thread.Sleep(100);
        }

        //Debug.Log(string.Format("音频长度:byte[{0}],memoryStream[{1}]", audio_total_len, memoryStream.Length));
        //添加音频头,否则无法播放
        Utils.WAVE_Header wave_Header  = Utils.getWave_Header((int)memoryStream.Length + 44);
        byte[]            audio_header = Utils.StructToBytes(wave_Header);
        memoryStream.Position = 0;
        memoryStream.Write(audio_header, 0, audio_header.Length);
        memoryStream.Position = 0;
        if (filename != null)
        {
            FileStream fileStream = new FileStream(path + "/" + filename, FileMode.Create, FileAccess.Write);
            memoryStream.WriteTo(fileStream);
            memoryStream.Close();
            fileStream.Close();
        }
        return(synth_status);
    }
Beispiel #9
0
        // [TestMethod()]
        public void MSCTest()
        {
            // int winSize = 5; // TODO: 初始化为适当的值
            var target    = new MSC(); // TODO: 初始化为适当的值
            var matReader = new MatlabMatrixReader <double>(@"F:\3506\15chemometrics\RIPP_DEMO\src\RIPP\testdata\X.mat");
            var input     = matReader.ReadMatrix();


            var actual = target.Process((Matrix)input, RIPP.Lib.MathLib.VectorType.Row);
            var writer = new MatlabMatrixWriter(@"F:\3506\15chemometrics\RIPP_DEMO\src\RIPP\testdata\filter\out_msc_my.mat");

            writer.WriteMatrix <double>(actual, "dd");
            writer.Close();


            writer = new MatlabMatrixWriter(@"F:\3506\15chemometrics\RIPP_DEMO\src\RIPP\testdata\filter\out_msc_my_m.mat");
            writer.WriteMatrix <double>(target.Mean.ToRowMatrix(), "m");
            writer.Close();



            //测试按列来
            var input2  = input.Transpose();
            var target2 = new MSC();

            actual = target2.Process((Matrix)input2, RIPP.Lib.MathLib.VectorType.Column);
            writer = new MatlabMatrixWriter(@"F:\3506\15chemometrics\RIPP_DEMO\src\RIPP\testdata\filter\out_msc_myColumn.mat");
            writer.WriteMatrix <double>(actual, "dColumn");
            writer.Close();

            writer = new MatlabMatrixWriter(@"F:\3506\15chemometrics\RIPP_DEMO\src\RIPP\testdata\filter\out_msc_my_mColumn.mat");
            writer.WriteMatrix <double>(target.Mean.ToRowMatrix(), "mColumn");
            writer.Close();



            //
            var target3 = new MSC();

            actual = target3.ProcessForPrediction((Matrix)input, RIPP.Lib.MathLib.VectorType.Row, target.Mean);
            writer = new MatlabMatrixWriter(@"F:\3506\15chemometrics\RIPP_DEMO\src\RIPP\testdata\filter\out_msc_my_ForPrediction.mat");
            writer.WriteMatrix <double>(actual, "dd");
            writer.Close();
            // Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #10
0
 //kiểm tra xem có chọn chưa và được phép phân quyền
 public void tstbmsc(DevExpress.XtraGrid.Views.Grid.GridView view)
 {
     try
     {
         if (view.GetRowCellValue(view.FocusedRowHandle, "ID").ToString() != "b7e767cb-2731-434c-a513-61ed7497db6f")
         {
             MSC F = new MSC();
             F.getrole(view.GetRowCellValue(view.FocusedRowHandle, "ID").ToString());
             F.Show();
         }
         else
         {
             DevExpress.XtraEditors.XtraMessageBox.Show("Bạn không được phân quyền cho ADMIN.", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
         }
     }
     catch
     {
         DevExpress.XtraEditors.XtraMessageBox.Show("Vui lòng chọn nhóm trước khi phân quyền.", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
     }
 }
Beispiel #11
0
 /// <summary>
 /// 单次识别
 /// </summary>
 /// <returns></returns>
 public RecogStatus SingleVoiceDistinguish()
 {
     try
     {
         Debug.Log(string.Format("登陆成功,语音识别正在加载..."));
         //语音转文字
         string session_params = "engine_type=cloud,sub = iat, domain = iat, language = zh_cn, accent = mandarin, sample_rate = 16000, result_type = plain, result_encoding = UTF-8 ,vad_eos = 5000";//可停止说话5秒保持语音识别状态
         string ssid           = Utils.Ptr2Str(MSC.QISRSessionBegin(string.Empty, session_params, ref ret));
         Debug.Log(string.Format("-->开启一次语音识别[{0}]", ssid));
         if (ret != (int)ErrorCode.MSP_SUCCESS)
         {
             Debug.Log("加载失败!"); return(RecogStatus.ISR_REC_NULL);
         }
         recoStatus = SingleSpeechRecognition(ssid);
         MSC.QISRSessionEnd(ssid, string.Empty);
     }
     catch (Exception e)
     {
         Debug.Log(e.Message);
     }
     return(recoStatus);
 }
Beispiel #12
0
    /// <summary>
    /// 语音唤醒方法
    /// </summary>
    /// <param name="sid"></param>
    private static void VoiceArousal(string sid)
    {
        string file = mic.startRecording("hx");

        if (file == string.Empty)
        {
            return;
        }
        //byte[] audio_buffer = GetFileData(file);
        byte[] audio_buffer = Utils.GetFileData(Environment.CurrentDirectory + "/wav/rec.wav");
        int    audio_size   = audio_buffer.Length;
        int    audio_count  = 0;

        while (audio_stat != audioStatus.MSP_AUDIO_SAMPLE_LAST)
        {
            int len = 10 * FRAME_LEN; //16k音频,10帧 (时长200ms)
            audio_stat = audioStatus.MSP_AUDIO_SAMPLE_CONTINUE;
            if (audio_size <= len)
            {
                len        = audio_size;
                audio_stat = audioStatus.MSP_AUDIO_SAMPLE_LAST; //最后一块
            }
            if (0 == audio_count)
            {
                audio_stat = audioStatus.MSP_AUDIO_SAMPLE_FIRST;
            }
            //Debug.Log(string.Format("{1} 音频长度[{0}]", len, DateTime.Now.Ticks));
            ret = MSC.QIVWAudioWrite(sid, audio_buffer.Skip(audio_count).Take(len).ToArray(), (uint)len, audio_stat);
            if (ret != (int)ErrorCode.MSP_SUCCESS)
            {
                Debug.Log(string.Format("{0} 语音唤醒失败:{1}", DateTime.Now.Ticks, ret)); return;
            }
            audio_count += len;
            audio_size  -= len;
            Thread.Sleep(200);
        }
    }
Beispiel #13
0
        public void MutableString_Characters1() {
            TestChars(MS("αβ", RubyEncoding.UTF8), "αβ");
            TestChars(MS(Encoding.UTF8.GetBytes("αβ"), RubyEncoding.UTF8), "αβ");
            TestChars(MS("α", RubyEncoding.UTF8).Append('β'), "αβ");
            TestChars(MS(Encoding.UTF8.GetBytes("ab"), RubyEncoding.UTF8), "ab");
            TestChars(MS(Encoding.UTF8.GetBytes("ab"), RubyEncoding.Binary), "ab");

            var sjis = RubyEncoding.KCodeSJIS.StrictEncoding.GetBytes("あ");
            var beta = Encoding.UTF8.GetBytes("β");
            var x = new byte[] { (byte)'x' };
            var uinvalid = new byte[] { 0xff };
            var u12345 = new byte[] { 0xF0, 0x92, 0x8D, 0x85 }; // \u{12345} in UTF-8

            var c_sjis = new MSC('あ');
            var c_beta = new MSC('β');
            var c_x = new MSC('x');
            var c_uinvalid = new MSC(uinvalid);
            var s_u12345 = Encoding.UTF8.GetString(u12345);

            Assert(beta.Length == 2);

            // binary:
            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(sjis, x, sjis, x), RubyEncoding.KCodeSJIS),
                c_sjis, c_x, c_sjis, c_x
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, x), RubyEncoding.Binary),
                new MSC((char)beta[0]), new MSC((char)beta[1]), new MSC('x') 
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, beta, x, x), RubyEncoding.UTF8),
                c_beta, c_beta, c_x, c_x
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, uinvalid, uinvalid, beta, x, x, uinvalid), RubyEncoding.UTF8),
                c_beta, c_uinvalid, c_uinvalid, c_beta, c_x, c_x, c_uinvalid
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(u12345, beta), RubyEncoding.UTF8),
                new MSC(s_u12345[0]), new MSC(s_u12345[1]), c_beta
            );

            // string:
            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8),
                new MSC('α'), new MSC(s_u12345[0]), new MSC(s_u12345[1]), c_x, c_beta
            );

            TestChars(
                MutableString.CreateMutable(BinaryEncoding.Instance.GetString(Encoding.UTF8.GetBytes("xβ")), RubyEncoding.Binary),
                c_x, new MSC((char)beta[0]), new MSC((char)beta[1])
            );

            // chars:
            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8).Remove(4, 1),
                new MSC('α'), new MSC(s_u12345[0]), new MSC(s_u12345[1]), c_x
            );

            // remaining:
            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, uinvalid, uinvalid, beta, x, x, uinvalid), RubyEncoding.UTF8), 
                MutableString.CreateBinary(Utils.Concatenate(uinvalid, beta, x, x, uinvalid), RubyEncoding.UTF8),
                c_beta, c_uinvalid
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(uinvalid, uinvalid, uinvalid), RubyEncoding.UTF8),
                MutableString.CreateBinary(uinvalid, RubyEncoding.UTF8),
                c_uinvalid, c_uinvalid
            );

            TestChars(
                MutableString.CreateBinary(uinvalid, RubyEncoding.UTF8),
                MutableString.CreateBinary(new byte[0], RubyEncoding.UTF8),
                c_uinvalid
            );

            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8),
                MutableString.CreateMutable(s_u12345[1] + "xβ", RubyEncoding.UTF8),
                new MSC('α'), new MSC(s_u12345[0])
            );

            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8).Remove(4, 1),
                MutableString.CreateMutable(s_u12345[1] + "x", RubyEncoding.UTF8),
                new MSC('α'), new MSC(s_u12345[0])
            );
        }
Beispiel #14
0
 public static void MSCLogout()
 {
     MSC.MSPLogout();
 }
Beispiel #15
0
    /// <summary>
    /// 语音识别方法
    /// </summary>
    /// <param name="sid"></param>
    public static void SpeechRecognition(List <VoiceData> VoiceBuffer)
    {
        audio_stat = audioStatus.MSP_AUDIO_SAMPLE_CONTINUE;
        ep_status  = epStatus.MSP_EP_LOOKING_FOR_SPEECH;
        recoStatus = RecogStatus.ISR_REC_STATUS_SUCCESS;
        sid        = Utils.Ptr2Str(MSC.QISRSessionBegin(string.Empty, speech_param, ref ret));
        Debug.Log(string.Format("-->开启一次语音识别[{0}]", sid));
        if (ret != (int)ErrorCode.MSP_SUCCESS)
        {
            Debug.Log("加载失败!"); return;
        }

        for (int i = 0; i < VoiceBuffer.Count(); i++)
        {
            audio_stat = audioStatus.MSP_AUDIO_SAMPLE_CONTINUE;
            if (i == 0)
            {
                audio_stat = audioStatus.MSP_AUDIO_SAMPLE_FIRST;
            }
            ret = MSC.QISRAudioWrite(sid, VoiceBuffer[i].data, (uint)VoiceBuffer[i].data.Length, audio_stat, ref ep_status, ref recoStatus);
            if ((int)ErrorCode.MSP_SUCCESS != ret)
            {
                MSC.QISRSessionEnd(sid, null);
            }
        }

        ret = MSC.QISRAudioWrite(sid, null, 0, audioStatus.MSP_AUDIO_SAMPLE_LAST, ref ep_status, ref recoStatus);
        if ((int)ErrorCode.MSP_SUCCESS != ret)
        {
            Debug.Log("\nQISRAudioWrite failed! error code:" + ret);
            return;
        }

        while (RecogStatus.ISR_REC_STATUS_SPEECH_COMPLETE != recoStatus)
        {
            IntPtr rslt = MSC.QISRGetResult(sid, ref recoStatus, 0, ref ret);
            if ((int)ErrorCode.MSP_SUCCESS != ret)
            {
                Debug.Log("\nQISRGetResult failed, error code: " + ret);
                break;
            }
            if (IntPtr.Zero != rslt)
            {
                string tempRes = Utils.Ptr2Str(rslt);

                ask_rec_result = ask_rec_result + tempRes;
                if (ask_rec_result.Length >= BUFFER_SIZE)
                {
                    Debug.Log("\nno enough buffer for rec_result !\n");
                    break;
                }
            }
        }
        int errorcode = MSC.QISRSessionEnd(sid, "正常结束");

        //语音识别结果
        if (ask_rec_result.Length != 0)
        {
            FlowManage.P2MMode(nar);
            Debug.Log("识别结果是:" + ask_rec_result);
            ask_rec_result = "";
        }
    }
        public void MutableString_Characters1() {
            TestChars(MS("αβ", RubyEncoding.UTF8), "αβ");
            TestChars(MS(Encoding.UTF8.GetBytes("αβ"), RubyEncoding.UTF8), "αβ");
            TestChars(MS("α", RubyEncoding.UTF8).Append('β'), "αβ");
            TestChars(MS(Encoding.UTF8.GetBytes("ab"), RubyEncoding.UTF8), "ab");
            TestChars(MS(Encoding.UTF8.GetBytes("ab"), RubyEncoding.Binary), "ab");

            var beta = Encoding.UTF8.GetBytes("β");
            var x = new byte[] { (byte)'x' };
            var uinvalid = new byte[] { 0xff };
            var u12345 = new byte[] { 0xF0, 0x92, 0x8D, 0x85 }; // \u{12345} in UTF-8

            var c_sjis = new MSC('あ');
            var c_beta = new MSC('β');
            var c_x = new MSC('x');
            var c_uinvalid = new MSC(uinvalid);
            var s_u12345 = Encoding.UTF8.GetString(u12345, 0, u12345.Length);

            Assert(beta.Length == 2);

            // binary:
            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, x), RubyEncoding.Binary),
                new MSC((char)beta[0]), new MSC((char)beta[1]), new MSC('x') 
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, beta, x, x), RubyEncoding.UTF8),
                c_beta, c_beta, c_x, c_x
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, uinvalid, uinvalid, beta, x, x, uinvalid), RubyEncoding.UTF8),
                c_beta, c_uinvalid, c_uinvalid, c_beta, c_x, c_x, c_uinvalid
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(u12345, beta), RubyEncoding.UTF8),
                new MSC(s_u12345[0], s_u12345[1]), c_beta
            );

            // string:
            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8),
                new MSC('α'), new MSC(s_u12345[0], s_u12345[1]), c_x, c_beta
            );

            var xBeta = Encoding.UTF8.GetBytes("xβ");
            TestChars(
                MutableString.CreateMutable(BinaryEncoding.Instance.GetString(xBeta, 0, xBeta.Length), RubyEncoding.Binary),
                c_x, new MSC((char)beta[0]), new MSC((char)beta[1])
            );

            // chars:
            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8).Remove(4, 1),
                new MSC('α'), new MSC(s_u12345[0], s_u12345[1]), c_x
            );

            // remaining:
            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(beta, uinvalid, uinvalid, beta, x, x, uinvalid), RubyEncoding.UTF8), 
                MutableString.CreateBinary(Utils.Concatenate(uinvalid, beta, x, x, uinvalid), RubyEncoding.UTF8),
                c_beta, c_uinvalid
            );

            TestChars(
                MutableString.CreateBinary(Utils.Concatenate(uinvalid, uinvalid, uinvalid), RubyEncoding.UTF8),
                MutableString.CreateBinary(uinvalid, RubyEncoding.UTF8),
                c_uinvalid, c_uinvalid
            );

            TestChars(
                MutableString.CreateBinary(uinvalid, RubyEncoding.UTF8),
                MutableString.CreateBinary(new byte[0], RubyEncoding.UTF8),
                c_uinvalid
            );

            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8),
                MutableString.CreateMutable("xβ", RubyEncoding.UTF8),
                new MSC('α'), new MSC(s_u12345[0], s_u12345[1])
            );

            TestChars(
                MutableString.CreateMutable("α" + s_u12345 + "xβ", RubyEncoding.UTF8).Remove(4, 1),
                MutableString.CreateMutable("x", RubyEncoding.UTF8),
                new MSC('α'), new MSC(s_u12345[0], s_u12345[1])
            );

#if !WIN8
            // all Unicode ecnodings
            foreach (var e in new[] { 
                RubyEncodingOps.UTF_16LE, RubyEncodingOps.UTF_16BE, 
                RubyEncodingOps.UTF_32LE, RubyEncodingOps.UTF_32BE,
                RubyEncodingOps.UTF_7, RubyEncodingOps.UTF_8 }) {

                TestChars(
                    MutableString.CreateMutable("α" + s_u12345 + "xβ", e),
                    new MSC('α'),
                    new MSC(s_u12345[0], s_u12345[1]),
                    new MSC('x'),
                    new MSC('β')
                );
            }
#endif
        }