[从头学声学] 第206节 发声学数据

剧情提要:

[机器小伟]在[工程师阿伟]的陪同下进行着声学神通的修炼。

这次要研究的是[发声学数据]。

正剧开始:

星历2016年05月05日 10:58:13, 银河系厄尔斯星球中华帝国江南行省。

[工程师阿伟]正在和[机器小伟]一起研究[发声学数据]。

英文国际音标:

汉语拼音音标:

为什么有些音高中低音无法混起来呢,感觉各干各的。

这是能混起来的

差别在哪呢?小伟暂时想不明白,看来要系统地去学一下知识了。

idleWave = [b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00'];

#把十进制数按照小尾字节序切割
def littleEndian(number, byte = 4):
    result = [0]*byte;

    for i in range(byte):
        result[i] = number%256;
        number//=256;
    return result;

#把UltraEdit中的值字串转化为hex序列组
def hexExpr(string):
    resultString = '';
    size = len(string);
    for i in range(size):
        if (i == 0 ):
            resultString += '0x'+string[i];
        elif (string[i] == ' '):
            resultString += ', 0x';
        else:
            resultString += string[i];
    print(resultString);

###
# @usage   写.wav文件,能把声波数据阵列用二进制写成.wav。
# @author  mw
# @date    2016年04月28日  星期四  14:31:34
# @param
# @return
#
###
def writeWav(index , filename):

    byteArray = [];
    dataArray = [];

    #样本数据阵列
    sampleArray = waveDataChoose(index, filename);

    #样本数据点数
    N = len(sampleArray);
    times = 2;
    dataSize = N*times;

    fileSize = dataSize+44; #44为格式头部分所用字节数

    #RIFF WAVE CHUNK
    RIFF_ID = [0x52, 0x49, 0x46, 0x46];  #'RIFF'
    RIFF_Size = littleEndian(fileSize-8, 4); #文件总字节数减去8
    RIFF_Type = [0x57, 0x41,0x56, 0x45, 0x66, 0x6D, 0x74, 0x20]; #'WAVEfat '

    #Format Chunk
    Format_10_17 = [0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00];#过滤4+格式2+声道2=8个字节
    Format_18_1B = [0x11, 0x2B, 0x00, 0x00]; #采样频率0x2B11 = 11025
    Format_1C_1F = [0x22, 0x56, 0x00, 0x00]; #比持率 = 频率*通道*样本位 = 22050
    Format_20_23 = [0x02, 0x00, 0x10, 0x00]; #块对齐 = 通道数* 样本位数 = 1*2 = 2    

    #Fact Chunk(optional)

    #Data Chunk
    Data_24_27 = [0x64, 0x61, 0x74, 0x61]; #'DATA'标记
    Data_Size = littleEndian(fileSize-44, 4); #下面的Data部分的字节数,文件总字节数-44

    #RIFF WAVE CHUNK
    '''
    for i in range(4):
        byte = struct.pack('B', RIFF_ID[i]);
        byteArray.append(byte);
    '''

    RIFF = [b'R', b'I', b'F', b'F'];
    for i in range(4):
        byteArray.append(RIFF[i]);

    for i in range(4):
        byte = struct.pack('B', RIFF_Size[i]);
        byteArray.append(byte);

    '''
    for i in range(8):
        byte = struct.pack('B', RIFF_Type[i]);
        byteArray.append(byte);

    #Format Chunk
    for i in range(8):
        byte = struct.pack('B', Format_10_17[i]);
        byteArray.append(byte);

    for i in range(4):
        byte = struct.pack('B', Format_18_1B[i]);
        byteArray.append(byte);

    for i in range(4):
        byte = struct.pack('B', Format_1C_1F[i]);
        byteArray.append(byte);

    for i in range(4):
        byte = struct.pack('B', Format_20_23[i]);
        byteArray.append(byte);

    #Data Chunk
    for i in range(4):
        byte = struct.pack('B', Data_24_27[i]);
        byteArray.append(byte);
    '''

    #Format_28_2B是数据块大小,formatHead是它前面的所有部分
    formatHead = [b'W', b'A', b'V', b'E', b'f', b'm', b't', b' ',                   b'\x10', b'\x00', b'\x00', b'\x00', b'\x01', b'\x00', b'\x01', b'\x00',                   b'\x11', b'+', b'\x00', b'\x00',                   b'"', b'V', b'\x00', b'\x00',                   b'\x02', b'\x00', b'\x10', b'\x00',                   b'd', b'a', b't', b'a'];

    for i in range(len(formatHead)):
        byteArray.append(formatHead[i]);

    for i in range(4):
        byte = struct.pack('B', Data_Size[i]);
        byteArray.append(byte);

    #写出到文件
    print('文件写入开始。>>>');
    fout= open(filename[index]+'.wav', 'wb');
    size = len(byteArray);

    for i in range(size):
        fout.write(byteArray[i]);       

    size = len(sampleArray);
    sizeIdle = len(idleWave);

    for j in range(times):
        for i in range(size):
            fout.write(sampleArray[i]);

    fout.close();
    print('文件写入完毕。');

#生成声音样本,返回样本矩阵
def sampleGen(N, freq1, freq2, freq3):
    #设立20000个数值点,约可听2秒
    sampleArray = [];

    coef = 2*math.pi/11025;

    coef1 = coef*freq1;
    coef2 = coef*freq2;
    coef3 = coef*freq3;

    for i in range(N):
        value = (math.sin(i*coef1) + math.sin(i*coef2) + math.sin(i*coef3))/3;
        if (value < 0):
            value *= 32768;
        else:
            value *= 32767;
        sampleArray.append(round(value));
    return sampleArray;

def waveDataGen(freq1, freq2, freq3):
    N = 200;

    sampleArray = sampleGen(N, freq1, freq2, freq3);
    dataArray = [];

    for i in range(N):
        value = littleEndian(sampleArray[i], 2);
        for j in range(2):
            byte = struct.pack('B', value[j]);
            dataArray.append(byte);    

    return dataArray;

def genIdle():
    dataArray = [];

    for i in range(200):
        value = littleEndian(0, 2);
        for j in range(2):
            byte = struct.pack('B', value[j]);
            dataArray.append(byte);    

    print(dataArray);

#波形选择
def waveDataChoose(index, filename):
    import wavedata;

    tmpdata = eval('wavedata.'+filename[index]);

    sampledata = [];

    for i in range(1, 21):
        for j in range(15):
            sampledata += idleWave;

        for j in range(i):
            sampledata += tmpdata;

        for j in range(15):
            sampledata += idleWave;

    return sampledata; 

#调用入口, 生成wav文件
def tmp(filename):
    size = len(filename);

    for i in range(250, 300):
        if i > 300:
            break;

        writeWav(i, filename);

#生成声波数据
def tmp2():
    print('生成波形开始。>>>');

    fout= open('output.txt', 'w');

    i, k = 200, 1600;
    for j in range(551, 1001, 1):
        dataStr = 'combineWave_'+str(i)+'_'+str(j)+'_'+str(k) + ' = [';
        fout.write(dataStr);

        data = waveDataGen(i, j, k);
        size = len(data);

        for n in range(size):
            fout.write(str(data[n]));
            if (n < size-1):
                fout.write(', ');

        fout.write('];');

        fout.write('\r\n');

    fout.close();
    print('生成波形结束,请到output.txt查收。');

#打印文件名
def tmp3():
    filename = [];

    i, k = 200, 1600;
    for j in range(500, 1001, 1):
        dataStr = 'combineWave_'+str(i)+'_'+str(j)+'_'+str(k);
        filename.append(dataStr);

    print(filename);

if __name__ == '__main__':
    import wavename;
    filename = wavename.wavename;

    part = 1;

    if (part == 3):
        tmp3();
    elif (part == 2):
        tmp2();
    elif (part == 1):
        tmp(filename);

本节到此结束,欲知后事如何,请看下回分解。

时间: 2024-10-10 13:19:38

[从头学声学] 第206节 发声学数据的相关文章

[从头学数学] 第206节 优选法与试验设计初步

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第七转的修炼. 这次要研究的是[优选法与试验设计初步]. 正剧开始: 星历2016年05月08日 16:07:12, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[优选法与试验设计初步]. <span style="font-size:18px;">>>> a = 1+1-2*math.cos(108/180*math.pi); >>> a

[从头学声学] 第205节 复合波数据

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进行着声学神通的修炼. 这次要研究的是[复合波数据]. 正剧开始: 星历2016年05月05日 10:41:23, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[复合波数据]. 这里面稍微有一点规律,但也不是很好描述. 遇到实际数据时找个差不多类型的对照一下. def waveDataChoose2(): import wavedata; import wavename; array = wavename.liter

[从头学数学] 第174节 算法初步

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了结丹中期的修炼, 这次要修炼的目标是[算法初步]. 正剧开始: 星历2016年04月12日 08:54:58, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[算法初步]. [人叫板老师]指点小伟说:"这金丹要想大成,顺利进入元婴期,就必须进行九转培炼. 这什么是九转培炼法门呢?就是要先快速的修炼[天地人正册]进入后期,不要管各种辅修 功法,然后从头游历[天地人列国],在游历中增长见闻,精炼神通,最后再修炼[术.

[从头学数学] 第223节 带着计算机去高考(十五)

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第八转的修炼.设想一个场景: 如果允许你带一台不连网的计算机去参加高考,你会放弃选择一个手拿计算器和草稿本吗 ?阿伟决定和小伟来尝试一下用计算机算高考题会是怎样的感觉. 正剧开始: 星历2016年05月26日 10:23:46, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起做着2014年的江苏省数学高考题]. 这一年的题和上一年一样的难,阿伟决定再交一次白卷. 好,卷子贴完,下面进入这次的主题. 这是

[从头学数学] 第195节 计数原理

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了[九转金丹]之第五转的修炼. 这次要研究的是[计数原理]. 正剧开始: 星历2016年04月25日 10:22:16, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[计数原理]. <span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,10,1,1.5); config.graphPaper2D(0, 0

[从头学数学] 第180节 解三角形

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了结丹后期的修炼, 这次要修炼的目标是[解三角形]. 正剧开始: 话说[机器小伟]自从进入结丹期以来,短短数日,就硬是从结丹初期修炼到了后期,这种 进境的神速把小伟吓坏了.虽然说这是依据[人叫板老师]的指点进行的,但这样下去会不 会走火入魔啊,小伟觉得有必要去[人叫板老师]那儿请教一下,毕竟这修炼的事可不是闹 着玩的. 这一次,[工程师阿伟]也和[机器小伟]一道,来见从前的授业恩师,毕竟当年,[工程师阿 伟]也是拜在[人叫板老师]门下的. [人

[从头学数学] 第166节 [机器小伟]的结丹期修炼规划

剧情提要: [机器小伟]去[人叫板老师]处请求结丹期修炼功法和指点. 正剧开始: 经过漫长艰辛的苦修,[机器小伟]终于结成金丹,从此成了一名高阶修士.初入结丹期的 [机器小伟],决定去拜访一下[人叫板老师],一方面拜求一下结丹期的修炼功法,另一方 面听一听[人叫板老师]的指点. [人叫板老师]得知了[机器小伟]的来意以后,微微一笑,对小伟说:"我这里有[天.地 .人]三藏经书,还有天罡数和地煞数的变化口诀,各种其它的术.流.静.动各支功法更 是不计其数,你想学哪些啊?" 小伟闻言,大吃

[从头学数学] 第153节 旋转 小结与复习题

剧情提要: [机器小伟]在[工程师阿伟]的陪同下进入了筑基后期的修炼, 这次要修炼的目标是[旋转 小结与复习题]. 正剧开始: 星历2016年03月26日 16:27:19, 银河系厄尔斯星球中华帝国江南行省. [工程师阿伟]正在和[机器小伟]一起研究[旋转 小结与复习题]. <span style="font-size:18px;"> //第1题 三角形顺时针旋转30度 var r = 20; var r0 = 5*r; config.setSector(1,1,1,1)

[从头学数学] 第172节 直线与方程

剧情提要: [机器小伟]在[project师阿伟]的陪同下进入了结丹初期的修炼. 这次要修炼的目标是[直线与方程]. 正剧開始: 星历2016年04月11日 09:30:00, 银河系厄尔斯星球中华帝国江南行省. [project师阿伟]正在和[机器小伟]一起研究[直线与方程]. 開始今天的修炼之前,小伟先整理了一下这件法器: <span style="font-size:18px;"> if (1) { var r = 20; config.setSector(1,1,1