帖子

[demo分享] Python直接调用msc.dll完成语音识别asr

  [复制链接]
  • TA的每日心情
    开心
    2017-7-18 09:18
  • 签到天数: 1 天

    [LV.1]初来乍到

    802236  楼主| RYHAN 发表于 2016-11-11 17:40:16 1#
    本帖最后由 RYHAN 于 2018-5-3 20:58 编辑

    在上次直接调用dll实现tts后,持续完成了生成音频以及直接调用耳机播放合成的音频。
    今天抽空研究对接asr,代码一共两个版本:

    v1.读取音频 ,调用msc
    v2.读取耳麦,调用msc

    ps:过程中参考论坛内其他同学的代码,并完成demo编写


    HandlerMscIsr.py
    1. #! /usr/bin/env python
    2. # coding=utf-8

    3. __author__ = 'ryhan'


    4. # 以下代码解决输出乱码问题
    5. import sys
    6. # print sys.getdefaultencoding()
    7. reload(sys)
    8. sys.setdefaultencoding('utf-8')
    9. # print sys.getdefaultencoding()

    10. from ctypes import *
    11. import time

    12. sys.path.append('.')

    13. dll = windll.LoadLibrary("msc.dll")

    14. # print dll.MSPLogin
    15. # print dll.QTTSSessionBegin
    16. # print dll.QTTSTextPut
    17. # print dll.QTTSAudioGet
    18. # print dll.QTTSSessionEnd

    19. uname = "973214924@qq.com"
    20. upass = ""

    21. login_params = "appid = 自己的id, work_dir = ."
    22. session_begin_params = "sub=iat,aue=speex-wb;7,result_type=plain,result_encoding=utf8,language=zh_cn,accent=mandarin,sample_rate=16000,domain=music,vad_bos=1000,vad_eos=1000"
    23. grammar_id = None  # '346c55176c3a5fc69750a3068b1a8457'

    24. FRAME_LEN = 640  # Byte

    25. MSP_SUCCESS = 0
    26. # 端点数据
    27. MSP_EP_LOOKING_FOR_SPEECH = 0
    28. MSP_EP_IN_SPEECH = 1
    29. MSP_EP_AFTER_SPEECH = 3
    30. MSP_EP_TIMEOUT = 4
    31. MSP_EP_ERROR = 5
    32. MSP_EP_MAX_SPEECH = 6
    33. MSP_EP_IDLE = 7
    34. # 音频情况
    35. MSP_AUDIO_SAMPLE_INIT = 0x00
    36. MSP_AUDIO_SAMPLE_FIRST = 0x01
    37. MSP_AUDIO_SAMPLE_CONTINUE = 0x02
    38. MSP_AUDIO_SAMPLE_LAST = 0x04
    39. # 识别状态
    40. MSP_REC_STATUS_SUCCESS = 0
    41. MSP_REC_STATUS_NO_MATCH = 1
    42. MSP_REC_STATUS_INCOMPLETE = 2
    43. MSP_REC_STATUS_NON_SPEECH_DETECTED = 3
    44. MSP_REC_STATUS_SPEECH_DETECTED = 4
    45. MSP_REC_STATUS_COMPLETE = 5
    46. MSP_REC_STATUS_MAX_CPU_TIME = 6
    47. MSP_REC_STATUS_MAX_SPEECH = 7
    48. MSP_REC_STATUS_STOPPED = 8
    49. MSP_REC_STATUS_REJECTED = 9
    50. MSP_REC_STATUS_NO_SPEECH_FOUND = 10
    51. MSP_REC_STATUS_FAILURE = MSP_REC_STATUS_NO_MATCH

    52. filename = "tts_sample.wav"
    53. filename = "iflytek01.wav"
    54. # filename = "ryhan.wav"


    55. class Msp:
    56.     def __init__(self):
    57.         pass

    58.     def login(self):
    59.         ret = dll.MSPLogin(None, None, login_params)
    60.         print('MSPLogin =>'), ret

    61.         pass

    62.     def isr(self, audiofile, session_begin_params, grammar_id):
    63.         ret = c_int()
    64.         sessionID = dll.QISRSessionBegin(grammar_id, session_begin_params, byref(ret))
    65.         print 'QISRSessionBegin => sessionID:', sessionID, 'ret:', ret.value

    66.         # 每秒【1000ms】  16000 次 * 16 bit 【20B】 ,每毫秒:1.6 * 16bit 【1.6*2B】 = 32Byte
    67.         # 1帧音频20ms【640B】 每次写入 10帧=200ms 【6400B】

    68.         piceLne = FRAME_LEN * 20
    69.         epStatus = c_int(0)
    70.         recogStatus = c_int(0)

    71.         wavFile = open(audiofile, 'rb')
    72.         wavData = wavFile.read(piceLne)

    73.         ret = dll.QISRAudioWrite(sessionID, wavData, len(wavData), MSP_AUDIO_SAMPLE_FIRST, byref(epStatus),
    74.                                  byref(recogStatus))
    75.         print 'len(wavData):', len(
    76.             wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', epStatus, 'recogStatus:', recogStatus

    77.         while wavData:
    78.             wavData = wavFile.read(piceLne)

    79.             if len(wavData) == 0:
    80.                 break

    81.             ret = dll.QISRAudioWrite(sessionID, wavData, len(wavData), MSP_AUDIO_SAMPLE_CONTINUE, byref(epStatus),
    82.                                      byref(recogStatus))
    83.             print 'len(wavData):', len(
    84.                 wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', epStatus, 'recogStatus:', recogStatus
    85.             time.sleep(0.2)

    86.         ret = dll.QISRAudioWrite(sessionID, None, 0, MSP_AUDIO_SAMPLE_LAST, byref(epStatus),
    87.                                  byref(recogStatus))
    88.         print 'len(wavData):', len(
    89.             wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', epStatus, 'recogStatus:', recogStatus


    90.         # -- 获取音频
    91.         laststr = ''
    92.         while recogStatus.value != MSP_REC_STATUS_COMPLETE:
    93.             ret = c_int()
    94.             dll.QISRGetResult.restype = c_char_p
    95.             retstr = dll.QISRGetResult(sessionID, byref(recogStatus), 0, byref(ret))
    96.             if retstr is not None:
    97.                 laststr += retstr
    98.             print 'ret:', ret, 'recogStatus:', recogStatus

    99.             time.sleep(0.2)

    100.         print '*' * 20, 'laststr:', '*' * 20
    101.         print laststr
    102.         print '*' * 20, 'laststr:', '*' * 20

    103.     pass


    104. if __name__ == "__main__":
    105.     msp = Msp()

    106.     msp.login()
    107.     msp.isr(filename, session_begin_params, grammar_id)
    复制代码


    HandlerMscIsr_v2.py
    1. #! /usr/bin/env python
    2. # coding=utf-8

    3. __author__ = 'ryhan'


    4. # 以下代码解决输出乱码问题
    5. import sys
    6. # print sys.getdefaultencoding()
    7. reload(sys)
    8. sys.setdefaultencoding('utf-8')
    9. # print sys.getdefaultencoding()

    10. from ctypes import *
    11. import time
    12. import pyaudio

    13. sys.path.append('.')

    14. dll = windll.LoadLibrary("msc.dll")

    15. # print dll.MSPLogin
    16. # print dll.QTTSSessionBegin
    17. # print dll.QTTSTextPut
    18. # print dll.QTTSAudioGet
    19. # print dll.QTTSSessionEnd

    20. uname = "973214924@qq.com"
    21. upass = ""

    22. login_params = "appid = 自己的id, work_dir = ."
    23. session_begin_params = "sub=iat,aue=speex-wb;7,result_type=plain,result_encoding=utf8,language=zh_cn," \
    24.                        "accent=mandarin,sample_rate=16000,domain=music,vad_bos=2000,vad_eos=2000"
    25. grammar_id = None  # '346c55176c3a5fc69750a3068b1a8457'

    26. FRAME_LEN = 640  # Byte

    27. MSP_SUCCESS = 0
    28. # 端点数据
    29. MSP_EP_LOOKING_FOR_SPEECH = 0
    30. MSP_EP_IN_SPEECH = 1
    31. MSP_EP_AFTER_SPEECH = 3
    32. MSP_EP_TIMEOUT = 4
    33. MSP_EP_ERROR = 5
    34. MSP_EP_MAX_SPEECH = 6
    35. MSP_EP_IDLE = 7
    36. # 音频情况
    37. MSP_AUDIO_SAMPLE_INIT = 0x00
    38. MSP_AUDIO_SAMPLE_FIRST = 0x01
    39. MSP_AUDIO_SAMPLE_CONTINUE = 0x02
    40. MSP_AUDIO_SAMPLE_LAST = 0x04
    41. # 识别状态
    42. MSP_REC_STATUS_SUCCESS = 0
    43. MSP_REC_STATUS_NO_MATCH = 1
    44. MSP_REC_STATUS_INCOMPLETE = 2
    45. MSP_REC_STATUS_NON_SPEECH_DETECTED = 3
    46. MSP_REC_STATUS_SPEECH_DETECTED = 4
    47. MSP_REC_STATUS_COMPLETE = 5
    48. MSP_REC_STATUS_MAX_CPU_TIME = 6
    49. MSP_REC_STATUS_MAX_SPEECH = 7
    50. MSP_REC_STATUS_STOPPED = 8
    51. MSP_REC_STATUS_REJECTED = 9
    52. MSP_REC_STATUS_NO_SPEECH_FOUND = 10
    53. MSP_REC_STATUS_FAILURE = MSP_REC_STATUS_NO_MATCH

    54. filename = "tts_sample.wav"
    55. filename = "iflytek01.wav"
    56. # filename = "ryhan.wav"


    57. class Msp:
    58.     def __init__(self):
    59.         pass

    60.     def login(self):
    61.         ret = dll.MSPLogin(None, None, login_params)
    62.         print('MSPLogin =>'), ret

    63.         pass

    64.     def isr(self, audiofile, session_begin_params, grammar_id):
    65.         ret = c_int()
    66.         sessionID = dll.QISRSessionBegin(grammar_id, session_begin_params, byref(ret))
    67.         print 'QISRSessionBegin => sessionID:', sessionID, 'ret:', ret.value

    68.         # 每秒【1000ms】  16000 次 * 16 bit 【20B】 ,每毫秒:1.6 * 16bit 【1.6*2B】 = 32Byte
    69.         # 1帧音频20ms【640B】 每次写入 10帧=200ms 【6400B】


    70.         p = pyaudio.PyAudio()
    71.         stream = p.open(rate=16000,
    72.                         channels=1,
    73.                         format=pyaudio.paInt16,
    74.                         input=True,
    75.                         frames_per_buffer=2048)

    76.         epStatus = c_int(0)
    77.         recogStatus = c_int(0)

    78.         wavData = stream.read(2048)

    79.         ret = dll.QISRAudioWrite(sessionID, wavData, len(wavData), MSP_AUDIO_SAMPLE_FIRST, byref(epStatus),
    80.                                  byref(recogStatus))
    81.         print 'len(wavData):', len(
    82.             wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', epStatus, 'recogStatus:', recogStatus

    83.         times = 0
    84.         while True:
    85.             wavData = stream.read(2048)
    86.             ret = dll.QISRAudioWrite(sessionID, wavData, len(wavData), MSP_AUDIO_SAMPLE_CONTINUE, byref(epStatus),
    87.                                      byref(recogStatus))
    88.             print 'len(wavData):', len(
    89.                 wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', epStatus, 'recogStatus:', recogStatus
    90.             time.sleep(0.02)
    91.             times += 1

    92.             if epStatus.value != MSP_EP_IN_SPEECH:
    93.                 break

    94.         ret = dll.QISRAudioWrite(sessionID, None, 0, MSP_AUDIO_SAMPLE_LAST, byref(epStatus),
    95.                                  byref(recogStatus))
    96.         print 'len(wavData):', len(
    97.             wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', epStatus, 'recogStatus:', recogStatus


    98.         # -- 获取音频
    99.         laststr = ''
    100.         while recogStatus.value != MSP_REC_STATUS_COMPLETE:
    101.             ret = c_int()
    102.             dll.QISRGetResult.restype = c_char_p
    103.             retstr = dll.QISRGetResult(sessionID, byref(recogStatus), 0, byref(ret))
    104.             if retstr is not None:
    105.                 laststr += retstr
    106.             print 'ret:', ret, 'recogStatus:', recogStatus

    107.             time.sleep(0.2)

    108.         print '*' * 20, 'laststr:', '*' * 20
    109.         print laststr
    110.         print '*' * 20, 'laststr:', '*' * 20

    111.     pass


    112. if __name__ == "__main__":
    113.     msp = Msp()

    114.     msp.login()
    115.     msp.isr(filename, session_begin_params, grammar_id)
    复制代码





    IflytekYun.zip

    8.33 MB, 下载次数: 125

    售价: 5 语点  [记录]

    代码都在这了

    评分

    参与人数 4语点 +34 收起 理由
    xv44586 + 5 山寨
    lihuang1004@163 + 10 正要找这个呢

    查看全部评分

    阿卜肚拉 发表于 2016-11-16 09:49:45
    2#
    dll.QISRGetResult.restype = c_char_p
    请问这句是做什么的呢,我如果注释掉的话,dll.QISRGetResult返回的就是null

    retstr = dll.QISRGetResult(sessionID, byref(recogStatus), 0, byref(ret))
    这里为什么每次返回的都是一串不同的数字呢




    使用道具 举报 回复
     楼主| RYHAN 发表于 2016-11-19 16:36:17
    3#
    阿卜肚拉 发表于 2016-11-16 09:49
    dll.QISRGetResult.restype = c_char_p
    请问这句是做什么的呢,我如果注释掉的话,dll.QISRGetResult返回的 ...

    dll.QISRGetResult.restype = c_char_p

    这句话是定义获取的返回值类型,这个函数 在c++里面定义的是char* 所以要这么用,让python自动包装返回值。

    返回数字 其实应该是内存的地址

    使用道具 举报 回复
    lihuang1004@163 发表于 2016-11-24 21:38:34
    4#
    msc.dll也在附件里吧?是不是C++的动态链接库啊
    使用道具 举报 回复
    Waspss 发表于 2016-11-25 22:12:53
    5#
    阿卜肚拉 发表于 2016-11-16 09:49
    dll.QISRGetResult.restype = c_char_p
    请问这句是做什么的呢,我如果注释掉的话,dll.QISRGetResult返回的 ...

    厉害 厉害........
    使用道具 举报 回复
    Reidzhang 发表于 2016-12-7 10:03:14
    6#
    厉害厉害,感谢楼主分享,感觉最后都可以加个dll.QISRSessionEnd(sessionID,None),这样重复调用不会报错。
    使用道具 举报 回复
    1002466215@qq.c 发表于 2017-3-8 09:44:23
    7#
    不错不错,学习了
    使用道具 举报 回复
    bigmaocxd 发表于 2017-4-22 10:44:56
    8#
    厉害厉害,正找这个,学习一下
    使用道具 举报 回复
    ljj1234 发表于 2017-6-21 17:07:08
    9#
    楼主厉害,真需要这个,果断支持
    使用道具 举报 回复
    smartfrog 发表于 2017-6-28 22:30:43
    10#
    正好用上,谢谢楼主分享
    使用道具 举报 回复