标签:
剧情提要:正剧开始:
星历2016年05月06日 13:54:48, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[声学的原理]。
这个音高频率表是这样算出来的:
[32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55.0, 58.27, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110.0, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220.0, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440.0, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880.0, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760.0, 1864.655, 1975.533, 2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963, 3322.438, 3520.0, 3729.31, 3951.066] def tmp(): #公比 半音 q = 2**(1/12); #A4 = (+9) A4 = 440; #C1 = (-36) C1 = A4/q**45; toneFrequence = []; for i in range(-36, 48): toneFrequence.append(round(A4*q**(i-9), 3)); print(toneFrequence);
>>> 203.91*5+90.22 1109.77 >>> 203.91*5+90.22*2 1199.99 >>> [440, 469.865, 495.0, 528.598, 556.875, 594.672, 626.484, 669.006, 704.795, 752.632, 792.894, 846.711, 892.006] #三分损益法(黄钟大吕音) def tmp(): #公比 半音 q = 2**(1/1200); #A4 = (+9) A4 = 440; tmpfreq = A4; toneFrequence = []; for i in range(13): toneFrequence.append(round(tmpfreq, 3)); if (i%2==0): tmpfreq *= q**(113.69); else: tmpfreq *= q**(90.22); print(toneFrequence);
阿伟给小伟做了一个乐音遍历工具,可以听出国际谱中的所有音符。
本来可以传到酷狗的,但想了想,还是传优酷了,尽管很短,
还要看很长时间的广告。
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 = []; mode = 2; #样本数据阵列 sampleArray = []; if mode == 1: sampleArray = waveDataChoose(index, filename); elif mode == 2: sampleArray = waveDataChoose_2(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('文件写入开始。>>>'); s = ''; if mode == 1: s = filename[index]+'.wav'; elif mode == 2: s = 'randMusic'+str(index)+'.wav'; fout= open(s, '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, freq): #设立20000个数值点,约可听2秒 sampleArray = []; coef = 2*math.pi*freq/11025; #音色调节 weight = [1, 2.55, 2.13, 1.98, 1.57, 1.23]; total = sum(weight); for i in range(N): xvalue = coef*i; yvalue = (weight[0]*math.sin(xvalue) + weight[1]*math.sin(xvalue*2)+ weight[2]*math.sin(xvalue*3) + weight[3]*math.sin(xvalue*4) + weight[4]*math.sin(xvalue*5)+ weight[5]*math.sin(xvalue*6))/total; if (yvalue < 0): yvalue *= 32768; else: yvalue *= 32767; sampleArray.append(round(yvalue)); return sampleArray; def waveDataGen(freq): N = 200; sampleArray = sampleGen(N, freq); 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; def waveDataChoose_2(filename): import wavedata; size = len(filename); sampledata = []; for i in range(300): #index_1 = random.randint(24, size-1-36); idleCircle = random.randint(2, 8); longIdleCircle = random.randint(8, 20); musicCircle = random.randint(2, 15); tmpdata = eval('wavedata.'+filename[i%size]); for j in range(musicCircle): sampledata += tmpdata; for j in range(idleCircle): sampledata += idleWave; if (i%longIdleCircle == 0): for j in range(longIdleCircle): sampledata += idleWave; for i in range(30): sampledata += idleWave; return sampledata; #调用入口, 生成wav文件 def tmp(filename): size = len(filename); for i in range(size): if i > 300: break; writeWav(i, filename); def tmp_2(index, filename): writeWav(index, filename); #生成声波数据 def tmp2(): print('生成波形开始。>>>'); fout= open('output.txt', 'w'); frequence = [32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55.0, 58.27, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110.0, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220.0, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440.0, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880.0, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760.0, 1864.655, 1975.533, 2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963, 3322.438, 3520.0, 3729.31, 3951.066]; size = len(frequence); for i in range(size): dataStr = 'musicfreq_'+str(frequence[i]).replace('.', 'p') + ' = ['; fout.write(dataStr); data = waveDataGen(frequence[i]); size_1 = len(data); for n in range(size_1): fout.write(str(data[n])); if (n < size_1-1): fout.write(', '); fout.write('];'); fout.write('\r\n'); fout.close(); print('生成波形结束,请到output.txt查收。'); #打印文件名 def tmp3(): filename = []; frequence = [32.703, 34.648, 36.708, 38.891, 41.203, 43.654, 46.249, 48.999, 51.913, 55.0, 58.27, 61.735, 65.406, 69.296, 73.416, 77.782, 82.407, 87.307, 92.499, 97.999, 103.826, 110.0, 116.541, 123.471, 130.813, 138.591, 146.832, 155.563, 164.814, 174.614, 184.997, 195.998, 207.652, 220.0, 233.082, 246.942, 261.626, 277.183, 293.665, 311.127, 329.628, 349.228, 369.994, 391.995, 415.305, 440.0, 466.164, 493.883, 523.251, 554.365, 587.33, 622.254, 659.255, 698.456, 739.989, 783.991, 830.609, 880.0, 932.328, 987.767, 1046.502, 1108.731, 1174.659, 1244.508, 1318.51, 1396.913, 1479.978, 1567.982, 1661.219, 1760.0, 1864.655, 1975.533, 2093.005, 2217.461, 2349.318, 2489.016, 2637.02, 2793.826, 2959.955, 3135.963, 3322.438, 3520.0, 3729.31, 3951.066]; size = len(frequence); for i in range(size): dataStr = 'musicfreq_'+str(frequence[i]).replace('.', 'p'); filename.append(dataStr); print(filename); if __name__ == '__main__': part = 1; if (part == 3): tmp3(); elif (part == 2): tmp2(); elif (part == 1): import wavename; filename = wavename.wavename; tmp_2(3, filename);
#生成声音样本,返回样本矩阵 def sampleGen_2(N, freq1, freq2): #设立20000个数值点,约可听2秒 sampleArray = []; coef = 2*math.pi/11025; #音色调节 weight = [1.53, 1]; total = sum(weight); for i in range(N): xcoef_1 = coef*i*freq1; xcoef_2 = coef*i*freq2; yvalue = (weight[0]*math.sin(xcoef_1)+ weight[1]*math.sin(xcoef_2))/total; if (yvalue < 0): yvalue *= 32768; else: yvalue *= 32767; sampleArray.append(round(yvalue)); return sampleArray; def waveDataGen_2(freq1, freq2): N = 200; sampleArray = sampleGen_2(N, freq1, freq2); 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 tmp2_2(): print('生成波形开始。>>>'); fout= open('output.txt', 'w'); frequence = [[240,2400], [235,2100], [390,2300], [370,1900], [610,1900], [585,1710], [850, 1610], [820, 1530], [750, 940], [700, 760], [600, 1170], [500, 700], [460, 1310], [360, 640], [300, 1390], [250, 595]]; size = len(frequence); for i in range(size): dataStr = 'primaryTone_'+ str(frequence[i][0])+'_'+str(frequence[i][1]) + ' = ['; fout.write(dataStr); data = waveDataGen_2(frequence[i][0], frequence[i][1]); size_1 = len(data); for n in range(size_1): fout.write(str(data[n])); if (n < size_1-1): fout.write(', '); fout.write('];'); fout.write('\r\n'); fout.close(); print('生成波形结束,请到output.txt查收。'); #生成声波数据 def tmp3_2(): filename = []; frequence = [[240,2400], [235,2100], [390,2300], [370,1900], [610,1900], [585,1710], [850, 1610], [820, 1530], [750, 940], [700, 760], [600, 1170], [500, 700], [460, 1310], [360, 640], [300, 1390], [250, 595]]; size = len(frequence); for i in range(size): dataStr = 'primaryTone_'+ str(frequence[i][0])+'_'+str(frequence[i][1]); filename.append(dataStr); print(filename); if __name__ == '__main__': part = 1; if (part == 3): tmp3_2(); elif (part == 2): tmp2_2(); elif (part == 1): import wavename; filename = wavename.wavename; tmp_2(5, filename);
本节到此结束,欲知后事如何,请看下回分解。
标签:
原文地址:http://blog.csdn.net/mwsister/article/details/51331074