单词及变形的连续发音

缘由:

  1. GoldenDict(GD)能自动读出分组的第一个音频文件并发音. 这个发音往往是单词的原型. 如果你需要GD读出单词的变形(譬如: 复数, 过去分词, 现在分词…)就必须首先找到有这些发音文件的(发音)词典, 并逐一点取而后发音(也许可以使用快捷键加快点击速度)
  2. 本帖所涉及程序的目的: 在GD输入查询标的后, GD能自动全部逐一读出所有变形音频或相关短语.

今天准备动手做了
不知道有没有朋友有类似需求?

目标: 在GD上查询标的时自动读出指定的音频内容, 可以是以下内容及其组合

  1. 单词原型
  2. 单词变形
  3. 例句

支持格式:

  1. SPX(这个优先, 主要是因为手里的发音字典比较全面的是SPX格式)
  2. MP3
  3. AAC(ACC)/WAV

实现方式:

  1. GoldenDict + Python(3)
1 Like

期待大咖的大作

<本楼所载源代码转载请注明出处>
ms.py

#[email protected]
import sys
from speex import *
import winsound
from zipfile import ZipFile
import time
import os

def decode_spx(vocoded):
    if vocoded[0:4] == b'OggS':
        spx_header = SpeexHeader.from_packet(vocoded[28:])
    mode = spx_header.mode
    if mode == 0:
        multi = 2
        mode = 1
    else:
        multi = 1
    decoder = SpeexDecoder(mode)
    wav_header_size = 44 
    wav_head_1 = b'RIFF' 
    wav_head_2 = (b'WAVE' + b'fmt ' + int.to_bytes(16, 4, 'little') + int.to_bytes(1, 2, 'little')
            + int.to_bytes(spx_header.nb_channels, 2, 'little') + int.to_bytes(spx_header.rate//spx_header.nb_channels*multi, 4, 'little')
            + int.to_bytes(spx_header.rate*multi,  4, 'little')
            + int.to_bytes(2*spx_header.nb_channels, 2, 'little') + int.to_bytes(16, 2, 'little') + b'data')
    i = 0 
    pcm = b''
    while i < len(vocoded):
        if vocoded[i:i+4] == b'OggS':
            granual_no = int.from_bytes(vocoded[i+6:i+14], 'little')
            if granual_no > 0:
            # audio data
                page_seg = int.from_bytes(vocoded[i+26:i+27], 'little')
                start_pos = i + 27 + page_seg
                for j in range(41):
                    packet_size = int.from_bytes(vocoded[i+27+j: i+27+j+1], 'little')
                    pcm += decoder.decode(vocoded[start_pos:start_pos+ packet_size])
                    start_pos += packet_size
        i += 1
    file_size = wav_header_size + len(pcm) - 8
    data_size = len(pcm) 
    wav_data = wav_head_1 + int.to_bytes(file_size, 4, 'little')
    wav_data += wav_head_2 + int.to_bytes(data_size, 4, 'little')
    wav_data += pcm

    return wav_data

def locate_file(voc_str):
    index_file = os.path.dirname(sys.argv[0]) + "\\ms.lo"
    with open(index_file, "r") as f:
        for line in f:
            file_list = line.rstrip().split('::')
            if file_list[0] == voc_str:
                file_list = file_list[1].split('|')
                break
    voc_zip = os.path.dirname(sys.argv[0]) + "\\ms.zip"
    with ZipFile(voc_zip, 'r') as zf:
        for name in file_list:
            try:
                wav_data = decode_spx(zf.read(name))
            except:
                print("no audio file", name)
                continue
            winsound.PlaySound(wav_data, winsound.SND_MEMORY)
            time.sleep(0.5)
    return file_list

def main(argv):
    voc_str = argv[0]
    locate_file(voc_str)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("usage: ms/whatever.py word")
        exit(1)
    main(sys.argv[1:])

1. ms.lo文件及格式, 本文件指定一次性读出内容, 分隔符号分别是**::|**


2 ms.zip, 放置音频文件(内置音频文件格式目前只支持SPX, 音频文件无父目录, 与GD资源文件要求相同)

3. 所需要的库
image

1. GD的词典配置


2. 应用举例

大神这么多发音词库。羡慕,期待您的大作。