skip to Main Content

I’m using azure speech sdk to do pronunciation assessment, it works fine when i used api provide by azure, but when i use speech sdk the result is not correct. I follow the sample from cognitive services speech sdk

Here is the code that i used for sdk

    def speech_recognition_with_pull_stream(self):
    class WavFileReaderCallback(speechsdk.audio.PullAudioInputStreamCallback):
        def __init__(self, filename: str):
            super().__init__()
            self._file_h = wave.open(filename, mode=None)

            self.sample_width = self._file_h.getsampwidth()

            assert self._file_h.getnchannels() == 1
            assert self._file_h.getsampwidth() == 2
            # assert self._file_h.getframerate() == 16000  #comment this line because every .wav file read is 48000
            assert self._file_h.getcomptype() == 'NONE'

        def read(self, buffer: memoryview) -> int:
            size = buffer.nbytes
            print(size)
            print(len(buffer))
            frames = self._file_h.readframes(len(buffer) // self.sample_width)

            buffer[:len(frames)] = frames

            return len(frames)

        def close(self):
            self._file_h.close()

    speech_key = os.getenv('AZURE_SUBSCRIPTION_KEY')
    service_region = os.getenv('AZURE_REGION')
    speech_config = speechsdk.SpeechConfig(subscription=speech_key, region=service_region)

    # specify the audio format
    wave_format = speechsdk.audio.AudioStreamFormat(samples_per_second=16000, bits_per_sample=16, channels=1)

    # setup the audio stream
    callback = WavFileReaderCallback('/Users/146072/Downloads/58638f26-ed07-40b7-8672-1948c814bd69.wav')
    stream = speechsdk.audio.PullAudioInputStream(callback, wave_format)
    audio_config = speechsdk.audio.AudioConfig(stream=stream)

    # instantiate the speech recognizer with pull stream input
    speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config, language='en-US')

    reference_text = 'We had a great time taking a long walk outside in the morning'
    pronunciation_assessment_config = speechsdk.PronunciationAssessmentConfig(
        reference_text=reference_text,
        grading_system=PronunciationAssessmentGradingSystem.HundredMark,
        granularity=PronunciationAssessmentGranularity.Word,
    )
    pronunciation_assessment_config.phoneme_alphabet = "IPA"
    pronunciation_assessment_config.apply_to(speech_recognizer)
    speech_recognition_result = speech_recognizer.recognize_once()
    print(speech_recognition_result.text)

    # The pronunciation assessment result as a Speech SDK object
    pronunciation_assessment_result = speechsdk.PronunciationAssessmentResult(speech_recognition_result)
    print(pronunciation_assessment_result)

    # The pronunciation assessment result as a JSON string
    pronunciation_assessment_result_json = speech_recognition_result.properties.get(
        speechsdk.PropertyId.SpeechServiceResponse_JsonResult
    )
    print(pronunciation_assessment_result_json)

    return json.loads(pronunciation_assessment_result_json)

and here is the result from sdk

"PronunciationAssessment": {
    "AccuracyScore": 26,
    "FluencyScore": 9,
    "CompletenessScore": 46,
    "PronScore": 19.8
  },

and here is the code for api call

    def ackaud(self):
    #    f.save(audio)
    # print('file uploaded successfully')

    # a generator which reads audio data chunk by chunk
    # the audio_source can be any audio input stream which provides read() method, e.g. audio file, microphone, memory stream, etc.
    def get_chunk(audio_source, chunk_size=1024):
        while True:
            # time.sleep(chunk_size / 32000) # to simulate human speaking rate
            chunk = audio_source.read(chunk_size)
            if not chunk:
                # global uploadFinishTime
                # uploadFinishTime = time.time()
                break
            yield chunk

    # build pronunciation assessment parameters
    referenceText = 'We had a great time taking a long walk outside in the morning. '

    pronAssessmentParamsJson = "{"ReferenceText":"%s","GradingSystem":"HundredMark","Dimension":"Comprehensive","EnableMiscue":"True"}" % referenceText
    pronAssessmentParamsBase64 = base64.b64encode(bytes(pronAssessmentParamsJson, 'utf-8'))
    pronAssessmentParams = str(pronAssessmentParamsBase64, "utf-8")

    subscription_key = os.getenv('AZURE_SUBSCRIPTION_KEY')
    region = os.getenv('AZURE_REGION')

    # build request
    url = "https://%s.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=%s&usePipelineVersion=0" % (
    region, 'en-US')
    headers = {'Accept': 'application/json;text/xml',
               'Connection': 'Keep-Alive',
               'Content-Type': 'audio/wav; codecs=audio/pcm; samplerate=16000',
               'Ocp-Apim-Subscription-Key': subscription_key,
               'Pronunciation-Assessment': pronAssessmentParams,
               'Transfer-Encoding': 'chunked',
               'Expect': '100-continue'}

    audioFile = open('/Users/146072/Downloads/58638f26-ed07-40b7-8672-1948c814bd69.wav', 'rb')
    # audioFile = f
    # send request with chunked data
    response = requests.post(url=url, data=get_chunk(audioFile), headers=headers)
    # getResponseTime = time.time()
    audioFile.close()

    # latency = getResponseTime - uploadFinishTime
    # print("Latency = %sms" % int(latency * 1000))

    return response.json()

and here is the result from api

"AccuracyScore": 100,
"FluencyScore": 100,
"CompletenessScore": 100,
"PronScore": 100,

Am i doing anything wrong in the setup? Thanks a lot.

2

Answers


  1. Chosen as BEST ANSWER

    After playing around with samples_per_second the code seem to work correct.


  2. Install the latest Speech SDK 1.26.0 as REST API uses version 3.1 that is generally available.

    Here is the document to install the speech SDK.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search