[Python] How can I save my results to a json file in speech studio?

Discussão em 'Python' iniciado por Stack, Agosto 26, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using Azure Pronunciation Assessment with speech to text. I'm using the code provided in the website to assess several single word audios.

    def pronunciation_assessment_continuous_from_file():
    """Performs continuous pronunciation assessment asynchronously with input from an audio file.
    See more information at https://aka.ms/csspeech/pa"""

    import difflib
    import json

    # Creates an instance of a speech config with specified subscription key and service region.
    # Replace with your own subscription key and service region (e.g., "westus").
    speech_config = speechsdk.SpeechConfig(subscription="YourSubscriptionKey", region="YourServiceRegion")
    # provide a WAV file as an example. Replace it with your own.
    audio_config = speechsdk.audio.AudioConfig(filename="YourAudioFile.wav")

    reference_text = "your reference text"
    # create pronunciation assessment config, set grading system, granularity and if enable miscue based on your requirement.
    enable_miscue = True
    enable_prosody_assessment = True
    pronunciation_config = speechsdk.PronunciationAssessmentConfig(
    reference_text=reference_text,
    grading_system=speechsdk.PronunciationAssessmentGradingSystem.HundredMark,
    granularity=speechsdk.PronunciationAssessmentGranularity.Phoneme,
    enable_miscue=enable_miscue)
    if enable_prosody_assessment:
    pronunciation_config.enable_prosody_assessment()

    # Creates a speech recognizer using a file as audio input.
    language = 'en-US'
    speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, language=language, audio_config=audio_config)
    # apply pronunciation assessment config to speech recognizer
    pronunciation_config.apply_to(speech_recognizer)

    done = False
    recognized_words = []
    fluency_scores = []
    prosody_scores = []
    durations = []

    def stop_cb(evt: speechsdk.SessionEventArgs):
    """callback that signals to stop continuous recognition upon receiving an event `evt`"""
    print('CLOSING on {}'.format(evt))
    nonlocal done
    done = True

    def recognized(evt: speechsdk.SpeechRecognitionEventArgs):
    print('pronunciation assessment for: {}'.format(evt.result.text))
    pronunciation_result = speechsdk.PronunciationAssessmentResult(evt.result)
    print(' Accuracy score: {}, pronunciation score: {}, completeness score : {}, fluency score: {}, prosody score: {}'.format(
    pronunciation_result.accuracy_score, pronunciation_result.pronunciation_score,
    pronunciation_result.completeness_score, pronunciation_result.fluency_score, pronunciation_result.prosody_score
    ))
    nonlocal recognized_words, fluency_scores, durations, prosody_scores
    recognized_words += pronunciation_result.words
    fluency_scores.append(pronunciation_result.fluency_score)
    prosody_scores.append(pronunciation_result.prosody_score)
    json_result = evt.result.properties.get(speechsdk.PropertyId.SpeechServiceResponse_JsonResult)
    jo = json.loads(json_result)
    nb = jo['NBest'][0]
    durations.append(sum([int(w['Duration']) for w in nb['Words']]))

    # Connect callbacks to the events fired by the speech recognizer
    speech_recognizer.recognized.connect(recognized)
    speech_recognizer.session_started.connect(lambda evt: print('SESSION STARTED: {}'.format(evt)))
    speech_recognizer.session_stopped.connect(lambda evt: print('SESSION STOPPED {}'.format(evt)))
    speech_recognizer.canceled.connect(lambda evt: print('CANCELED {}'.format(evt)))
    # stop continuous recognition on either session stopped or canceled events
    speech_recognizer.session_stopped.connect(stop_cb)
    speech_recognizer.canceled.connect(stop_cb)

    # Start continuous pronunciation assessment
    speech_recognizer.start_continuous_recognition()
    while not done:
    time.sleep(.5)

    speech_recognizer.stop_continuous_recognition()

    # we need to convert the reference text to lower case, and split to words, then remove the punctuations.
    if language == 'zh-CN':
    # Use jieba package to split words for Chinese
    import jieba
    import zhon.hanzi
    jieba.suggest_freq([x.word for x in recognized_words], True)
    reference_words = [w for w in jieba.cut(reference_text) if w not in zhon.hanzi.punctuation]
    else:
    reference_words = [w.strip(string.punctuation) for w in reference_text.lower().split()]

    # For continuous pronunciation assessment mode, the service won't return the words with `Insertion` or `Omission`
    # even if miscue is enabled.
    # We need to compare with the reference text after received all recognized words to get these error words.
    if enable_miscue:
    diff = difflib.SequenceMatcher(None, reference_words, [x.word.lower() for x in recognized_words])
    final_words = []
    for tag, i1, i2, j1, j2 in diff.get_opcodes():
    if tag in ['insert', 'replace']:
    for word in recognized_words[j1:j2]:
    if word.error_type == 'None':
    word._error_type = 'Insertion'
    final_words.append(word)
    if tag in ['delete', 'replace']:
    for word_text in reference_words[i1:i2]:
    word = speechsdk.PronunciationAssessmentWordResult({
    'Word': word_text,
    'PronunciationAssessment': {
    'ErrorType': 'Omission',
    }
    })
    final_words.append(word)
    if tag == 'equal':
    final_words += recognized_words[j1:j2]
    else:
    final_words = recognized_words

    # We can calculate whole accuracy by averaging
    final_accuracy_scores = []
    for word in final_words:
    if word.error_type == 'Insertion':
    continue
    else:
    final_accuracy_scores.append(word.accuracy_score)
    accuracy_score = sum(final_accuracy_scores) / len(final_accuracy_scores)
    # Re-calculate fluency score
    fluency_score = sum([x * y for (x, y) in zip(fluency_scores, durations)]) / sum(durations)
    # Calculate whole completeness score
    completeness_score = len([w for w in recognized_words if w.error_type == "None"]) / len(reference_words) * 100
    completeness_score = completeness_score if completeness_score <= 100 else 100
    # Re-calculate prosody score
    prosody_score = sum(prosody_scores) / len(prosody_scores)
    pron_score = accuracy_score * 0.4 + prosody_score * 0.2 + fluency_score * 0.2 + completeness_score * 0.2

    print(' Paragraph pronunciation score: {}, accuracy score: {}, completeness score: {}, fluency score: {}, prosody score: {}'.format(
    pron_score, accuracy_score, completeness_score, fluency_score, prosody_score
    ))

    for idx, word in enumerate(final_words):
    print(' {}: word: {}\taccuracy score: {}\terror type: {};'.format(
    idx + 1, word.word, word.accuracy_score, word.error_type
    ))


    It says that the output is a json output:

    [
    {
    "Id": "093715d1c7d34c8193377c63f780c447",
    "RecognitionStatus": "Success",
    "Offset": 11400000,
    "Duration": 8900000,
    "Channel": 0,
    "DisplayText": "Scrubs.",
    "SNR": 6.4204135,
    "NBest": [
    {
    "Confidence": 0.88077533,
    "Lexical": "scrubs",
    "ITN": "scrubs",
    "MaskedITN": "scrubs",
    "Display": "Scrubs.",
    "PronunciationAssessment": {
    "AccuracyScore": 54,
    "FluencyScore": 0,
    "ProsodyScore": 73.8,
    "CompletenessScore": 0,
    "PronScore": 25.6
    },
    "Words": [
    {
    "Word": "scrubs",
    "Offset": 11400000,
    "Duration": 8900000,
    "PronunciationAssessment": {
    "AccuracyScore": 54,
    "ErrorType": "Mispronunciation",
    "Feedback": {
    "Prosody": {
    "Break": {
    "ErrorTypes": [
    "None"
    ],
    "BreakLength": 0
    },
    "Intonation": {
    "ErrorTypes": [],
    "Monotone": {
    "SyllablePitchDeltaConfidence": 0.50218755
    }
    }
    }
    }
    },
    "Syllables": [
    {
    "Syllable": "skɹʌbz",
    "Grapheme": "scrubs",
    "PronunciationAssessment": {
    "AccuracyScore": 44
    },
    "Offset": 11400000,
    "Duration": 8900000
    }
    ],
    "Phonemes": [
    {
    "Phoneme": "s",
    "PronunciationAssessment": {
    "AccuracyScore": 10,
    "NBestPhonemes": [
    {
    "Phoneme": "z",
    "Score": 100
    },
    {
    "Phoneme": "s",
    "Score": 80
    },
    {
    "Phoneme": "t",
    "Score": 10
    },
    {
    "Phoneme": "k",
    "Score": 10
    },
    {
    "Phoneme": "ɪ",
    "Score": 9
    }
    ]
    },
    "Offset": 11400000,
    "Duration": 600000
    },
    {
    "Phoneme": "k",
    "PronunciationAssessment": {
    "AccuracyScore": 41,
    "NBestPhonemes": [
    {
    "Phoneme": "g",
    "Score": 100
    },
    {
    "Phoneme": "z",
    "Score": 82
    },
    {
    "Phoneme": "k",
    "Score": 62
    },
    {
    "Phoneme": "s",
    "Score": 50
    },
    {
    "Phoneme": "ɹ",
    "Score": 38
    }
    ]
    },
    "Offset": 12100000,
    "Duration": 2000000
    },
    {
    "Phoneme": "ɹ",
    "PronunciationAssessment": {
    "AccuracyScore": 34,
    "NBestPhonemes": [
    {
    "Phoneme": "ɹ",
    "Score": 100
    },
    {
    "Phoneme": "g",
    "Score": 44
    },
    {
    "Phoneme": "ɝ",
    "Score": 30
    },
    {
    "Phoneme": "u",
    "Score": 21
    },
    {
    "Phoneme": "ə",
    "Score": 13
    }
    ]
    },
    "Offset": 14200000,
    "Duration": 700000
    },
    {
    "Phoneme": "ʌ",
    "PronunciationAssessment": {
    "AccuracyScore": 41,
    "NBestPhonemes": [
    {
    "Phoneme": "u",
    "Score": 100
    },
    {
    "Phoneme": "ɹ",
    "Score": 95
    },
    {
    "Phoneme": "ʊ",
    "Score": 27
    },
    {
    "Phoneme": "ɝ",
    "Score": 23
    },
    {
    "Phoneme": "ʌ",
    "Score": 21
    }
    ]
    },
    "Offset": 15000000,
    "Duration": 1500000
    },
    {
    "Phoneme": "b",
    "PronunciationAssessment": {
    "AccuracyScore": 46,
    "NBestPhonemes": [
    {
    "Phoneme": "p",
    "Score": 100
    },
    {
    "Phoneme": "b",
    "Score": 52
    },
    {
    "Phoneme": "u",
    "Score": 40
    },
    {
    "Phoneme": "m",
    "Score": 19
    },
    {
    "Phoneme": "s",
    "Score": 13
    }
    ]
    },
    "Offset": 16600000,
    "Duration": 1300000
    },
    {
    "Phoneme": "z",
    "PronunciationAssessment": {
    "AccuracyScore": 61,
    "NBestPhonemes": [
    {
    "Phoneme": "s",
    "Score": 100
    },
    {
    "Phoneme": "z",
    "Score": 90
    },
    {
    "Phoneme": "p",
    "Score": 69
    },
    {
    "Phoneme": "oʊ",
    "Score": 32
    },
    {
    "Phoneme": "t",
    "Score": 24
    }
    ]
    },
    "Offset": 18000000,
    "Duration": 2300000
    }
    ]
    }
    ]
    }
    ]
    }
    ]


    I wish to save this to a "results = []" list. But I don't know which variable to append to my list. The sample code doesn't have a return statement so I don't know what to do. I've tried appending the variables "Accuracy score", "Pronunciation score", etc, but the scores are slightly different from the ones that I get if I manually do it on the "Try it out" website. Could anyone give some pointers as to what append to my results please, I don't have a background in programming?

    Continue reading...

Compartilhe esta Página