22.2.7 波形音频文件格式——WAV音频格式
偏移量 |
字节 |
数据 |
0000 |
4 |
字符串——“RIFF”(资源交换文件格式),文件由很多数据“块”组成,每一块数据由块的名称和块长组成。名称由4个ASCII字符组成。块长不包含块的名称和块长这个字段本身所需的8个字节,也就是说是“块”的实际长度。 |
0004 |
4 |
波形数据块的大小(文件大小-8)即从偏移0008开始到文件结束的大小 |
0008 |
4 |
字符串——“WAVE” |
000C |
4 |
字符串——“fmt ”(注意:fmt后面有一空格) |
0010 |
4 |
格式数据块的大小(16字节),即sizeof(PCMWAVEFORMATEX) |
0014 |
2 |
wf.wFormatTag = WAVE_FORMAT_PCM =1 |
0016 |
2 |
wf.nChannels |
0018 |
4 |
wf.nSamplesPerSec |
001C |
4 |
wf.nAvgBytesPerSec |
0020 |
2 |
wf.nBlockAlign |
0022 |
2 |
wf.wBitsPerSample //样本大小,当为8位及以下时,被解释为无符号整数,0x80表示无声。8位以上时无声为0 |
0024 |
4 |
字符串——“data” |
0028 |
4 |
波形数据的大小,即真正的声音数据的大小 |
002C |
n |
波形数据——声音数据 |
22.2.8 使用加法合成来生成波形声音(小号、双簧管、单簧管)
(1)每一种乐器由一系列的分音组成(小号12个分音,双簧管和单簧管各21个分音)
(2)PRT结构:存放每个分音的振幅和频率包络线的点的个数和各振幅和各频率。
(3)INS结构:为每种乐器的结构,存放乐音的总时间,分音的数量和所有分音振幅和频率。
(4)FillBuffer:先计算累计最大振幅。这个振幅在后面用于把采样按比例缩放到8位的样本大小。接着,按指定的频率开始采样,然后对每个分音的振幅和频率进行线性插值。
传入频率值和相位角,并调用SineGenerator函数正弦值并累加分音振幅,最后将振幅缩放到8位的样本大小。
【AddSynth程序】
/*------------------------------------------------------------------ ADDSYNTH.C —— additive Synthesis Sound Generator声音的加法合成器 (c)Charles Petzold,1998 -------------------------------------------------------------------*/ #include <Windows.h> #include <math.h> #include "AddSynth.h" #include "resource.h" #pragma comment(lib,"WINMM.LIB") #define ID_TIMER 1 //计时器 #define PI 3.14159 #define SAMPLE_RATE 22050 //采样频率 #define MAX_PARTIALS 21 //最大的泛音个数 BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); TCHAR szAppName[] = TEXT("AddSynth"); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iShowCmd) { if (-1 ==DialogBox(hInstance,szAppName,NULL,DlgProc)) { MessageBox(NULL, TEXT("This program require Windows NT!"), szAppName, MB_ICONERROR); } return 0; } //正弦波发生器 //根据相位角,求正弦波的振幅。并根据频率给出下一个相位角 double SineGenerator(double dFreq, double* pdAngle) { double dAmp; //振幅 dAmp = sin(*pdAngle); //计算振幅 *pdAngle += 2 * PI*dFreq / SAMPLE_RATE; //计算下一个样本的相位角 if (*pdAngle >= 2 * PI) *pdAngle -= 2 * PI; return dAmp; //返回振幅值 } //用合成的波形数据填充缓冲区 void FillBuffer(INS ins, PBYTE pBuffer, int iNumSamples) { static double dAngle[MAX_PARTIALS];//定义一个相位角数组 double dAmp, dFrq, dComp, dFrac; //定义振幅、频率、合成振幅、包络的线性插值比例因子 int i, iPrt, iMsecTime, iCompMaxAmp, iMaxAmp, iSmp;//定义i、泛音数组下标、每个样本的时间(毫秒) //最大合成振幅、最大振幅、样本号 //计算合成的最大振幅 iCompMaxAmp = 0; //在泛音集中循环以计算最大振幅 for (iPrt = 0; iPrt < ins.iNumPartials; iPrt++) { iMaxAmp = 0; for (i = 0; i < ins.pprt[iPrt].iNumAmp; i++) iMaxAmp = max(iMaxAmp, ins.pprt[iPrt].pEnvAmp[i].iValue); iCompMaxAmp += iMaxAmp; } //循环每个样本 for (iSmp = 0; iSmp < iNumSamples; iSmp++) { dComp = 0; iMsecTime = (int)(1000 * iSmp / SAMPLE_RATE);//取得每个样本的毫秒数 //循环每个泛音集 //以下循环在每个泛音中进行振幅和频率插值 for (iPrt = 0; iPrt < ins.iNumPartials; iPrt++) { dAmp = 0; //插值处的振幅 dFrq = 0; //插值处的频率 //对每个泛音集在指定的时间处(iMsecTime),进行振幅的插值 for (i = 0; i < ins.pprt[iPrt].iNumAmp-1; i++) { if (iMsecTime >= ins.pprt[iPrt].pEnvAmp[i].iTime && iMsecTime <= ins.pprt[iPrt].pEnvAmp[i+1].iTime) { //计算插值比例 dFrac = (iMsecTime - ins.pprt[iPrt].pEnvAmp[i].iTime) / (ins.pprt[iPrt].pEnvAmp[i + 1].iTime - ins.pprt[iPrt].pEnvAmp[i].iTime); //dAmp = v[i]+ dFrac*(v[i+1]-v[i]),即: //利用前两后两个振幅的插值比例,计算出插值处的振辐 dAmp = dFrac* ins.pprt[iPrt].pEnvAmp[i + 1].iValue + (1 - dFrac)*ins.pprt[iPrt].pEnvAmp[i].iValue; break; } } //对每个泛音集在指定的时间处(iMsecTime),进行频率的插值 for (i = 0; i < ins.pprt[iPrt].iNumFrq - 1; i++) { if (iMsecTime >= ins.pprt[iPrt].pEnvFrq[i].iTime && iMsecTime <= ins.pprt[iPrt].pEnvFrq[i + 1].iTime) { //计算插值比例 dFrac = (iMsecTime - ins.pprt[iPrt].pEnvFrq[i].iTime) / (ins.pprt[iPrt].pEnvFrq[i + 1].iTime - ins.pprt[iPrt].pEnvFrq[i].iTime); //dFrq = v[i]+ dFrac*(v[i+1]-v[i]),即: //利用前两后两个振幅的插值比例,计算出插值处的振辐 dFrq = dFrac* ins.pprt[iPrt].pEnvFrq[i + 1].iValue + (1 - dFrac)*ins.pprt[iPrt].pEnvFrq[i].iValue; break; } } //计算每个采样点处的合成振幅 dComp += dAmp*SineGenerator(dFrq, dAngle + iPrt); } pBuffer[iSmp] = (BYTE)(127 + 127 * dComp / iCompMaxAmp); //每个样本的振幅缩放到0-254之间 } } //创建声音波形文件 BOOL MakeWaveFile(INS ins, TCHAR* szFileName) { HANDLE hFile; PBYTE pBuffer; //缓冲区,用来接受一个音符的所有样本。 int iNumSamples,iPcmSize,iChunkSize; WAVEFORMATEX waveform; //定义一个波形音频结构变量 DWORD dwWritten; hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == NULL) return FALSE; //SAMPLE_RATE:采样率(样本数/秒),以下表示在iMsecTime毫秒内应采样的数量(取偶数个) iNumSamples = ((long)ins.iMsecTime*SAMPLE_RATE / 1000 + 1) / 2 * 2; iPcmSize = sizeof(PCMWAVEFORMAT);//取得脉冲编码调制结构体大小 //文件大小-8,即从第3个字段开始的WAV文件(见课本P1020图22-6) //0008-0014:12节字(分别为“WAVE”、“fmt ”、“格式数据块大小”字段 //0014-0024:PCMWAVEFORMAT结构体 //0024-002C:“data”、波形数据大小字段 //002C以后:波形数据(本例每个样本用1字节存储) iChunkSize = 12 + iPcmSize + 8 + iNumSamples; //除“RIFF”和“波形数据块大小”两个字段 if (NULL == (pBuffer = malloc(iNumSamples))) { CloseHandle(hFile); return FALSE; } FillBuffer(ins, pBuffer, iNumSamples); //初始化waveform结构 waveform.wFormatTag = WAVE_FORMAT_PCM; //脉冲编码调制格式 waveform.nChannels = 1;//单声道 waveform.nSamplesPerSec = SAMPLE_RATE; //采样率 waveform.nAvgBytesPerSec = SAMPLE_RATE; //平均数据传输率=nSamplesPerSec*nBlockAlign waveform.nBlockAlign = 1;//以1字节对齐,=nChannels*wBitsPerSample/8 waveform.wBitsPerSample = 8; //样本大小,用来表示样本的振幅,介于(0-255)之间 waveform.cbSize = 0; //对于PCM,必须为0; //将波形声音数据写入文件(文件格式:WAV格式) WriteFile(hFile, "RIFF", 4, &dwWritten, NULL); //"RIFF" WriteFile(hFile, &iChunkSize, 4, &dwWritten, NULL); //波形数据块的大小(文件大小-8),即W从AV文件第3字段开始 WriteFile(hFile, "WAVEfmt ", 8, &dwWritten, NULL); //第3、4字段:“WAVE”、“fmt ”(注意fmt后有一空格) WriteFile(hFile, &iPcmSize, 4, &dwWritten, NULL); //格式数据块的大小,即WAVEFORMATEX结构体 WriteFile(hFile, &waveform, sizeof(WAVEFORMATEX)-2, &dwWritten, NULL); //不含WAVEFORMATEX中的cbSize字段 WriteFile(hFile, "data", 4, &dwWritten, NULL); //“data”字段 WriteFile(hFile, &iNumSamples, 4, &dwWritten, NULL); //波形数据的大小 WriteFile(hFile, pBuffer, iNumSamples, &dwWritten, NULL); CloseHandle(hFile); free(pBuffer); if (dwWritten !=iNumSamples) { DeleteFile(szFileName); return FALSE; } return TRUE; } //测试和创建音频文件 void TestAndCreate(HWND hwnd, INS ins, TCHAR* szFileName, int idButton) { TCHAR szMessage[64]; //返回文件的属性,如果失败,返回-1 if (-1 != GetFileAttributes(szFileName)) { EnableWindow(GetDlgItem(hwnd, idButton), TRUE); } else { if (MakeWaveFile(ins,szFileName)) { EnableWindow(GetDlgItem(hwnd, idButton), TRUE); } else { wsprintf(szMessage, TEXT("Could not create %x."), szFileName); MessageBeep(MB_ICONEXCLAMATION); MessageBox(hwnd, szMessage, szAppName, MB_OK | MB_ICONEXCLAMATION); } } } BOOL CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static TCHAR* szTrum = TEXT("Trumpet.wav"); //小号 static TCHAR* szOboe = TEXT("Oboe.wav"); //双簧管 static TCHAR* szClar = TEXT("Clarinet.wav"); //单簧管 RECT rect; switch (message) { case WM_INITDIALOG: GetWindowRect(hwnd, &rect); SetWindowPos(hwnd, NULL, (GetSystemMetrics(SM_CXSCREEN) - rect.right + rect.left) / 2, (GetSystemMetrics(SM_CYSCREEN) - rect.bottom + rect.top) / 2, rect.right-rect.left,rect.bottom-rect.top,SWP_SHOWWINDOW); SetTimer(hwnd, ID_TIMER, 1, NULL); //设置定时器。目的是 return TRUE; case WM_TIMER: KillTimer(hwnd, ID_TIMER); SetCursor(LoadCursor(NULL,IDC_WAIT)); ShowCursor(TRUE); TestAndCreate(hwnd, insTrum, szTrum, IDC_TRUMPET); TestAndCreate(hwnd, insOboe, szOboe, IDC_OBOE); TestAndCreate(hwnd, insClar, szClar, IDC_CLARINET); SetDlgItemText(hwnd, IDC_TEXT, TEXT("")); SetFocus(GetDlgItem(hwnd, IDC_TRUMPET)); ShowCursor(FALSE); SetCursor(LoadCursor(NULL, IDC_ARROW)); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_TRUMPET: PlaySound(szTrum, NULL, SND_FILENAME | SND_SYNC); //播放小号 return TRUE; case IDC_OBOE: PlaySound(szOboe, NULL, SND_FILENAME | SND_SYNC); //播放双簧管 return TRUE; case IDC_CLARINET: PlaySound(szClar, NULL, SND_FILENAME | SND_SYNC); //播放单簧管 return TRUE; } break; case WM_SYSCOMMAND: switch (LOWORD(wParam)) { case SC_CLOSE: EndDialog(hwnd, 0); return TRUE; } break; } return FALSE; }
//AddSynth.h
/*------------------------------------------------------------------- ADDSYNTH.H -- Amplitude and Frequency Envelopes for 3 Instruments From "Computer Music Journal," Volume II, Number 2 -------------------------------------------------------------------*/ typedef struct { int iTime ; //时间 int iValue ; //该时间处,振幅的大小或该振幅出现的频率 } ENV ;//定义一个声音包络结构 typedef struct { int iNumAmp ; //分音中振幅的数量 ENV *pEnvAmp ; int iNumFrq ; //分音中频率的数量 ENV *pEnvFrq ; } PRT ;//定义一个泛音结构 typedef struct { int iMsecTime ; int iNumPartials ; PRT *pprt ; } INS ;//定义一个乐器结构 //以下定义小号的包络 ENV envTrumAmp01[] = { 1, 0, 20, 305, 36, 338, 141, 288, 237, 80, 360, 0 };//第1个分音,格式:时间,相应的振幅 ENV envTrumFrq01[] = { 1, 321, 16, 324, 32, 312, 109, 310, 317, 314, 360, 310 };//第2个分音:格式:时间、及该时间处相应振幅出现的频率 ENV envTrumAmp02[] = { 1, 0, 3, 0, 25, 317, 39, 361, 123, 295, 222, 40, 326, 0, 360, 0 }; ENV envTrumFrq02[] = { 1, 0, 2, 0, 3, 607, 16, 657, 24, 621, 133, 621, 275, 628, 326, 628, 327, 0, 360, 0 }; ENV envTrumAmp03[] = { 1, 0, 2, 0, 19, 100, 34, 369, 111, 342, 207, 41, 273, 0, 360, 0 }; ENV envTrumFrq03[] = { 1, 0, 2, 977, 5, 782, 15, 987, 24, 932, 128, 932, 217, 936, 273, 945, 275, 0, 360, 0 }; ENV envTrumAmp04[] = { 1, 0, 3, 0, 24, 113, 29, 257, 118, 231, 187, 35, 235, 0, 360, 0 }; ENV envTrumFrq04[] = { 1, 0, 2, 0, 3, 718, 16, 1335, 24, 1243, 108, 1240, 199, 1248, 235, 1248, 236, 0, 360, 0 }; ENV envTrumAmp05[] = { 1, 0, 27, 52, 34, 130, 110, 126, 191, 13, 234, 0, 360, 0 }; ENV envTrumFrq05[] = { 1, 1225, 9, 1569, 12, 1269, 21, 1573, 37, 1553, 97, 1552, 181, 1556, 234, 1566, 235, 0, 360, 0 }; ENV envTrumAmp06[] = { 1, 0, 46, 83, 64, 100, 100, 100, 189, 11, 221, 0, 360, 0 }; ENV envTrumFrq06[] = { 1, 1483, 12, 1572, 23, 1988, 33, 1864, 114, 1864, 177, 1868, 221, 1879, 222, 0, 360, 0 }; ENV envTrumAmp07[] = { 1, 0, 37, 39, 45, 77, 110, 79, 176, 11, 205, 0, 207, 0, 360, 0 }; ENV envTrumFrq07[] = { 1, 1792, 9, 1612, 29, 2242, 36, 2174, 93, 2176, 126, 2170, 205, 2188, 207, 0, 360, 0 }; ENV envTrumAmp08[] = { 1, 0, 2, 0, 28, 17, 43, 71, 109, 66, 172, 8, 201, 0, 360, 0 }; ENV envTrumFrq08[] = { 1, 0, 2, 1590, 29, 2539, 36, 2491, 114, 2481, 153, 2489, 201, 2491, 203, 0, 360, 0 }; ENV envTrumAmp09[] = { 1, 0, 2, 0, 29, 16, 43, 53, 54, 66, 105, 64, 165, 7, 191, 0, 360, 0 }; ENV envTrumFrq09[] = { 1, 0, 2, 1993, 25, 2121, 32, 2821, 37, 2796, 84, 2798, 105, 2792, 191, 2797, 192, 0, 360, 0 }; ENV envTrumAmp10[] = { 1, 0, 27, 6, 41, 25, 56, 29, 72, 22, 95, 24, 180, 0, 360, 0 }; ENV envTrumFrq10[] = { 1, 1792, 12, 1849, 32, 3131, 37, 3111, 114, 3103, 164, 3116, 180, 3116, 181, 0, 360, 0 }; ENV envTrumAmp11[] = { 1, 0, 2, 0, 37, 6, 55, 25, 88, 29, 114, 28, 164, 3, 186, 0, 360, 0 }; ENV envTrumFrq11[] = { 1, 0, 2, 1398, 31, 3419, 42, 3419, 91, 3419, 106, 3406, 150, 3421, 186, 3421, 187, 0, 360, 0 }; ENV envTrumAmp12[] = { 1, 0, 7, 0, 39, 3, 43, 8, 88, 11, 118, 9, 138, 3, 165, 0, 360, 0 }; ENV envTrumFrq12[] = { 1, 0, 6, 0, 7, 1806, 23, 2942, 36, 2759, 37, 3746, 50, 3723, 84, 3731, 110, 3721, 156, 3741, 165, 3620, 167, 0, 360, 0 }; //以下定义双簧管的包络 ENV envOboeAmp01[] = { 1, 0, 9, 0, 14, 10, 26, 10, 52, 140, 94, 187, 153, 170, 313, 0 }; ENV envOboeFrq01[] = { 1, 0, 8, 0, 9, 314, 25, 292, 43, 311, 144, 311, 272, 313, 313, 309 }; ENV envOboeAmp02[] = { 1, 0, 10, 0, 26, 17, 40, 139, 159, 115, 239, 62, 307, 0, 313, 0 }; ENV envOboeFrq02[] = { 1, 0, 9, 0, 10, 708, 16, 617, 41, 625, 105, 621, 265, 630, 307, 626, 308, 0, 313, 0 }; ENV envOboeAmp03[] = { 1, 0, 10, 0, 25, 19, 36, 163, 71, 191, 129, 187, 297, 0, 313, 0 }; ENV envOboeFrq03[] = { 1, 0, 9, 0, 10, 915, 21, 931, 72, 938, 148, 935, 249, 941, 297, 938, 299, 0, 313, 0 }; ENV envOboeAmp04[] = { 1, 0, 10, 0, 25, 16, 43, 221, 64, 173, 114, 171, 284, 0, 313, 0 }; ENV envOboeFrq04[] = { 1, 0, 9, 0, 10, 1209, 18, 1261, 37, 1246, 109, 1245, 238, 1255, 284, 1253, 285, 0, 313, 0 }; ENV envOboeAmp05[] = { 1, 0, 6, 0, 13, 3, 21, 0, 28, 0, 44, 210, 59, 238, 126, 224, 199, 85, 292, 0, 313, 0 }; ENV envOboeFrq05[] = { 1, 0, 5, 0, 6, 1553, 21, 1582, 25, 1237, 28, 1533, 35, 1564, 56, 1557, 113, 1555, 185, 1565, 292, 1566, 293, 0, 313, 0 }; ENV envOboeAmp06[] = { 1, 0, 13, 0, 17, 1, 24, 0, 30, 0, 41, 63, 67, 40, 121, 38, 278, 0, 313, 0 }; ENV envOboeFrq06[] = { 1, 0, 12, 0, 13, 1907, 22, 1883, 28, 1544, 30, 1856, 36, 1878, 52, 1871, 113, 1866, 169, 1878, 225, 1876, 278, 1891, 280, 0, 313, 0 }; ENV envOboeAmp07[] = { 1, 0, 8, 0, 14, 0, 21, 0, 32, 0, 37, 22, 119, 12, 146, 3, 194, 8, 256, 0, 313, 0 }; ENV envOboeFrq07[] = { 1, 0, 6, 0, 8, 1978, 21, 1923, 28, 1717, 32, 2191, 111, 2177, 188, 2193, 229, 2182, 256, 2194, 257, 0, 313, 0 }; ENV envOboeAmp08[] = { 1, 0, 6, 0, 14, 0, 21, 0, 37, 0, 66, 5, 106, 3, 129, 4, 199, 3, 235, 0, 313, 0 }; ENV envOboeFrq08[] = { 1, 0, 5, 0, 6, 2506, 21, 2491, 25, 1252, 37, 2523, 56, 2495, 110, 2489, 140, 2491, 195, 2502, 235, 2505, 237, 0, 313, 0 }; ENV envOboeAmp09[] = { 1, 0, 4, 0, 14, 0, 20, 0, 36, 0, 45, 32, 78, 24, 132, 25, 161, 15, 241, 0, 313, 0 }; ENV envOboeFrq09[] = { 1, 0, 2, 0, 4, 2783, 20, 2779, 29, 1286, 37, 2803, 80, 2806, 113, 2799, 167, 2813, 241, 2818, 242, 0, 313, 0 }; ENV envOboeAmp10[] = { 1, 0, 6, 0, 17, 2, 22, 0, 35, 0, 47, 121, 144, 112, 206, 21, 242, 0, 313, 0 }; ENV envOboeFrq10[] = { 1, 0, 5, 0, 6, 3123, 22, 3115, 29, 2229, 35, 3118, 70, 3117, 113, 3109, 200, 3130, 242, 3131, 243, 0, 313, 0 }; ENV envOboeAmp11[] = { 1, 0, 5, 0, 17, 1, 24, 0, 37, 0, 47, 70, 123, 67, 167, 44, 188, 16, 239, 0, 313, 0 }; ENV envOboeFrq11[] = { 1, 0, 4, 0, 5, 3285, 24, 3388, 29, 1270, 37, 3430, 76, 3429, 110, 3423, 194, 3444, 239, 3444, 241, 0, 313, 0 }; ENV envOboeAmp12[] = { 1, 0, 14, 1, 24, 0, 37, 0, 44, 49, 79, 42, 122, 46, 185, 8, 231, 0, 313, 0 }; ENV envOboeFrq12[] = { 1, 3627, 24, 3664, 29, 1690, 37, 3739, 90, 3742, 115, 3733, 187, 3760, 231, 3763, 233, 0, 313, 0 }; ENV envOboeAmp13[] = { 1, 0, 4, 0, 16, 0, 24, 0, 40, 0, 47, 27, 84, 22, 126, 24, 177, 7, 229, 0, 313, 0 }; ENV envOboeFrq13[] = { 1, 0, 2, 0, 4, 4081, 24, 4064, 30, 1350, 40, 4064, 57, 4049, 148, 4051, 181, 4074, 229, 4069, 230, 0, 313, 0 }; ENV envOboeAmp14[] = { 1, 0, 4, 0, 16, 0, 21, 0, 41, 0, 44, 13, 63, 8, 82, 7, 111, 10, 175, 0, 313, 0 }; ENV envOboeFrq14[] = { 1, 0, 2, 0, 4, 4321, 21, 4259, 29, 1238, 41, 4346, 61, 4367, 87, 4368, 102, 4357, 175, 4376, 176, 0, 313, 0 }; ENV envOboeAmp15[] = { 1, 0, 47, 0, 72, 3, 97, 3, 121, 1, 161, 2, 175, 0, 313, 0 }; ENV envOboeFrq15[] = { 1, 0, 45, 0, 47, 3164, 55, 4557, 68, 4662, 98, 4670, 142, 4661, 175, 4666, 176, 0, 313, 0 }; ENV envOboeAmp16[] = { 1, 0, 48, 0, 61, 4, 86, 4, 126, 3, 137, 5, 161, 0, 313, 0 }; ENV envOboeFrq16[] = { 1, 0, 47, 0, 48, 4567, 49, 4978, 75, 4990, 109, 4982, 138, 4985, 161, 4996, 163, 0, 313, 0 }; ENV envOboeAmp17[] = { 1, 0, 51, 0, 61, 5, 76, 3, 132, 3, 164, 2, 173, 0, 313, 0 }; ENV envOboeFrq17[] = { 1, 0, 49, 0, 51, 4634, 55, 5313, 66, 5301, 99, 5301, 129, 5292, 173, 5318, 175, 0, 313, 0 }; ENV envOboeAmp18[] = { 1, 0, 52, 0, 63, 2, 91, 3, 126, 3, 156, 2, 168, 0, 313, 0 }; ENV envOboeFrq18[] = { 1, 0, 51, 0, 52, 4729, 59, 5606, 92, 5611, 122, 5605, 152, 5611, 168, 5628, 169, 0, 313, 0 }; ENV envOboeAmp19[] = { 1, 0, 47, 0, 56, 2, 80, 1, 117, 2, 159, 1, 176, 0, 313, 0 }; ENV envOboeFrq19[] = { 1, 0, 45, 0, 47, 5772, 57, 5921, 86, 5928, 114, 5914, 150, 5938, 176, 5930, 177, 0, 313, 0 }; ENV envOboeAmp20[] = { 1, 0, 49, 0, 57, 2, 83, 2, 109, 1, 159, 3, 195, 0, 313, 0 }; ENV envOboeFrq20[] = { 1, 0, 48, 0, 49, 5369, 57, 6268, 76, 6230, 145, 6234, 184, 6263, 195, 6244, 196, 0, 313, 0 }; ENV envOboeAmp21[] = { 1, 0, 57, 0, 61, 0, 88, 1, 113, 0, 129, 1, 140, 0, 313, 0 }; ENV envOboeFrq21[] = { 1, 0, 56, 0, 57, 5477, 61, 6440, 71, 6550, 97, 6538, 122, 6554, 140, 6548, 141, 0, 313, 0 }; //以下定义单簧管的包络 ENV envClarAmp01[] = { 1, 0, 7, 0, 20, 6, 32, 73, 48, 445, 199, 361, 330, 0 }; ENV envClarFrq01[] = { 1, 0, 6, 0, 7, 282, 19, 368, 21, 314, 46, 310, 141, 312, 284, 313, 330, 314 }; ENV envClarAmp02[] = { 1, 0, 24, 0, 43, 22, 104, 2, 193, 4, 238, 10, 301, 0, 330, 0 }; ENV envClarFrq02[] = { 1, 0, 23, 0, 24, 629, 68, 619, 116, 616, 167, 633, 223, 624, 301, 627, 302, 0, 330, 0 }; ENV envClarAmp03[] = { 1, 0, 15, 0, 37, 12, 48, 159, 204, 122, 286, 17, 309, 0, 330, 0 }; ENV envClarFrq03[] = { 1, 0, 14, 0, 15, 803, 24, 928, 36, 898, 46, 931, 113, 939, 330, 942 }; ENV envClarAmp04[] = { 1, 0, 9, 0, 19, 2, 24, 0, 39, 0, 49, 26, 103, 3, 167, 5, 229, 10, 291, 0, 330, 0 }; ENV envClarFrq04[] = { 1, 0, 7, 0, 9, 1261, 24, 1314, 30, 327, 39, 1245, 105, 1243, 215, 1257, 246, 1249, 291, 1261, 292, 0, 330, 0 }; ENV envClarAmp05[] = { 1, 0, 6, 0, 18, 5, 25, 0, 39, 0, 54, 375, 212, 210, 266, 20, 295, 0, 330, 0 }; ENV envClarFrq05[] = { 1, 0, 5, 0, 6, 1572, 25, 1528, 32, 911, 38, 1560, 67, 1554, 127, 1565, 308, 1569, 309, 0, 330, 0 }; ENV envClarAmp06[] = { 1, 0, 3, 0, 11, 0, 15, 0, 41, 0, 48, 25, 108, 4, 216, 12, 282, 0, 330, 0 }; ENV envClarFrq06[] = { 1, 0, 2, 0, 3, 1934, 12, 1890, 33, 320, 46, 1862, 186, 1883, 282, 1875, 283, 0, 330, 0 }; ENV envClarAmp07[] = { 1, 0, 2, 0, 18, 1, 24, 0, 42, 0, 52, 108, 127, 46, 177, 42, 253, 0, 330, 0 }; ENV envClarFrq07[] = { 1, 0, 2, 2180, 24, 2148, 34, 795, 43, 2167, 113, 2193, 253, 2192, 255, 0, 330, 0 }; ENV envClarAmp08[] = { 1, 0, 2, 0, 14, 1, 23, 0, 43, 0, 52, 83, 110, 17, 199, 18, 242, 0, 330, 0 }; ENV envClarFrq08[] = { 1, 0, 2, 2458, 23, 2343, 33, 328, 45, 2472, 125, 2507, 242, 2510, 243, 0, 330, 0 }; ENV envClarAmp09[] = { 1, 0, 5, 0, 20, 2, 21, 3, 27, 0, 42, 0, 55, 127, 132, 73, 163, 71, 255, 0, 330, 0 }; ENV envClarFrq09[] = { 1, 0, 3, 0, 5, 2849, 27, 2688, 33, 964, 42, 2792, 128, 2822, 255, 2819, 256, 0, 330, 0 }; ENV envClarAmp10[] = { 1, 0, 5, 0, 23, 1, 30, 0, 47, 0, 54, 32, 92, 17, 232, 7, 247, 0, 330, 0 }; ENV envClarFrq10[] = { 1, 0, 3, 0, 5, 3173, 30, 3030, 39, 2320, 50, 3096, 134, 3136, 247, 3138, 248, 0, 330, 0 }; ENV envClarAmp11[] = { 1, 0, 23, 1, 28, 0, 39, 0, 59, 44, 122, 26, 153, 26, 262, 0, 330, 0 }; ENV envClarFrq11[] = { 1, 3313, 28, 3279, 34, 1768, 43, 3420, 127, 3448, 262, 3441, 264, 0, 330, 0 }; ENV envClarAmp12[] = { 1, 0, 10, 2, 21, 0, 46, 0, 52, 53, 158, 9, 206, 28, 255, 0, 330, 0 }; ENV envClarFrq12[] = { 1, 3756, 21, 3728, 33, 2095, 47, 3741, 136, 3762, 255, 3759, 256, 0, 330, 0 }; ENV envClarAmp13[] = { 1, 0, 3, 0, 16, 1, 29, 0, 41, 0, 46, 24, 52, 8, 77, 57, 192, 8, 250, 0, 330, 0 }; ENV envClarFrq13[] = { 1, 0, 2, 0, 3, 4152, 29, 3868, 36, 2240, 46, 4045, 85, 4049, 128, 4078, 181, 4078, 250, 4103, 251, 0, 330, 0 }; ENV envClarAmp14[] = { 1, 0, 3, 0, 16, 0, 20, 0, 48, 0, 56, 38, 110, 3, 188, 14, 228, 0, 330, 0 }; ENV envClarFrq14[] = { 1, 0, 2, 0, 3, 4213, 20, 4119, 36, 1566, 48, 4344, 130, 4388, 228, 4388, 229, 0, 330, 0 }; ENV envClarAmp15[] = { 1, 0, 5, 0, 23, 1, 28, 0, 50, 0, 77, 14, 202, 1, 219, 2, 247, 0, 330, 0 }; ENV envClarFrq15[] = { 1, 0, 3, 0, 5, 4624, 28, 4496, 33, 1012, 48, 4649, 122, 4703, 247, 4685, 248, 0, 330, 0 }; ENV envClarAmp16[] = { 1, 0, 14, 0, 24, 0, 38, 0, 64, 12, 104, 4, 145, 4, 215, 1, 238, 0, 330, 0 }; ENV envClarFrq16[] = { 1, 4928, 24, 4751, 36, 1072, 52, 4965, 117, 5006, 155, 5003, 198, 5020, 238, 3197, 239, 0, 330, 0 }; ENV envClarAmp17[] = { 1, 0, 58, 0, 95, 12, 136, 13, 201, 1, 220, 3, 233, 0, 330, 0 }; ENV envClarFrq17[] = { 1, 0, 45, 0, 46, 5005, 58, 3759, 63, 5285, 119, 5325, 180, 5325, 233, 5367, 234, 0, 330, 0 }; ENV envClarAmp18[] = { 1, 0, 50, 0, 61, 5, 100, 0, 141, 4, 185, 2, 208, 0, 330, 0 }; ENV envClarFrq18[] = { 1, 0, 48, 0, 50, 4926, 52, 5563, 94, 5628, 113, 5602, 137, 5634, 208, 5646, 210, 0, 330, 0 }; ENV envClarAmp19[] = { 1, 0, 58, 0, 63, 1, 85, 0, 140, 1, 171, 0, 183, 0, 330, 0 }; ENV envClarFrq19[] = { 1, 0, 56, 0, 58, 3938, 65, 5753, 79, 5930, 104, 5889, 152, 5916, 183, 5880, 184, 0, 330, 0 }; ENV envClarAmp20[] = { 1, 0, 50, 0, 64, 5, 103, 1, 139, 1, 177, 2, 219, 0, 330, 0 }; ENV envClarFrq20[] = { 1, 0, 48, 0, 50, 5192, 58, 6209, 121, 6266, 190, 6266, 204, 6238, 219, 6288, 220, 0, 330, 0 }; ENV envClarAmp21[] = { 1, 0, 70, 0, 79, 3, 113, 3, 141, 1, 206, 1, 219, 0, 330, 0 }; ENV envClarFrq21[] = { 1, 0, 69, 0, 70, 4245, 77, 6537, 116, 6567, 140, 6571, 176, 6564, 219, 6583, 220, 0, 330, 0 }; //以下定义小号的泛音集 PRT prtTrum [12] = { sizeof (envTrumAmp01) / sizeof (ENV), envTrumAmp01, sizeof (envTrumFrq01) / sizeof (ENV), envTrumFrq01, sizeof (envTrumAmp02) / sizeof (ENV), envTrumAmp02, sizeof (envTrumFrq02) / sizeof (ENV), envTrumFrq02, sizeof (envTrumAmp03) / sizeof (ENV), envTrumAmp03, sizeof (envTrumFrq03) / sizeof (ENV), envTrumFrq03, sizeof (envTrumAmp04) / sizeof (ENV), envTrumAmp04, sizeof (envTrumFrq04) / sizeof (ENV), envTrumFrq04, sizeof (envTrumAmp05) / sizeof (ENV), envTrumAmp05, sizeof (envTrumFrq05) / sizeof (ENV), envTrumFrq05, sizeof (envTrumAmp06) / sizeof (ENV), envTrumAmp06, sizeof (envTrumFrq06) / sizeof (ENV), envTrumFrq06, sizeof (envTrumAmp07) / sizeof (ENV), envTrumAmp07, sizeof (envTrumFrq07) / sizeof (ENV), envTrumFrq07, sizeof (envTrumAmp08) / sizeof (ENV), envTrumAmp08, sizeof (envTrumFrq08) / sizeof (ENV), envTrumFrq08, sizeof (envTrumAmp09) / sizeof (ENV), envTrumAmp09, sizeof (envTrumFrq09) / sizeof (ENV), envTrumFrq09, sizeof (envTrumAmp10) / sizeof (ENV), envTrumAmp10, sizeof (envTrumFrq10) / sizeof (ENV), envTrumFrq10, sizeof (envTrumAmp11) / sizeof (ENV), envTrumAmp11, sizeof (envTrumFrq11) / sizeof (ENV), envTrumFrq11, sizeof (envTrumAmp12) / sizeof (ENV), envTrumAmp12, sizeof (envTrumFrq12) / sizeof (ENV), envTrumFrq12 } ; //以下定义双簧管的泛音集 PRT prtOboe [21] = { sizeof (envOboeAmp01) / sizeof (ENV), envOboeAmp01, sizeof (envOboeFrq01) / sizeof (ENV), envOboeFrq01, sizeof (envOboeAmp02) / sizeof (ENV), envOboeAmp02, sizeof (envOboeFrq02) / sizeof (ENV), envOboeFrq02, sizeof (envOboeAmp03) / sizeof (ENV), envOboeAmp03, sizeof (envOboeFrq03) / sizeof (ENV), envOboeFrq03, sizeof (envOboeAmp04) / sizeof (ENV), envOboeAmp04, sizeof (envOboeFrq04) / sizeof (ENV), envOboeFrq04, sizeof (envOboeAmp05) / sizeof (ENV), envOboeAmp05, sizeof (envOboeFrq05) / sizeof (ENV), envOboeFrq05, sizeof (envOboeAmp06) / sizeof (ENV), envOboeAmp06, sizeof (envOboeFrq06) / sizeof (ENV), envOboeFrq06, sizeof (envOboeAmp07) / sizeof (ENV), envOboeAmp07, sizeof (envOboeFrq07) / sizeof (ENV), envOboeFrq07, sizeof (envOboeAmp08) / sizeof (ENV), envOboeAmp08, sizeof (envOboeFrq08) / sizeof (ENV), envOboeFrq08, sizeof (envOboeAmp09) / sizeof (ENV), envOboeAmp09, sizeof (envOboeFrq09) / sizeof (ENV), envOboeFrq09, sizeof (envOboeAmp10) / sizeof (ENV), envOboeAmp10, sizeof (envOboeFrq10) / sizeof (ENV), envOboeFrq10, sizeof (envOboeAmp11) / sizeof (ENV), envOboeAmp11, sizeof (envOboeFrq11) / sizeof (ENV), envOboeFrq11, sizeof (envOboeAmp12) / sizeof (ENV), envOboeAmp12, sizeof (envOboeFrq12) / sizeof (ENV), envOboeFrq12, sizeof (envOboeAmp13) / sizeof (ENV), envOboeAmp13, sizeof (envOboeFrq13) / sizeof (ENV), envOboeFrq13, sizeof (envOboeAmp14) / sizeof (ENV), envOboeAmp14, sizeof (envOboeFrq14) / sizeof (ENV), envOboeFrq14, sizeof (envOboeAmp15) / sizeof (ENV), envOboeAmp15, sizeof (envOboeFrq15) / sizeof (ENV), envOboeFrq15, sizeof (envOboeAmp16) / sizeof (ENV), envOboeAmp16, sizeof (envOboeFrq16) / sizeof (ENV), envOboeFrq16, sizeof (envOboeAmp17) / sizeof (ENV), envOboeAmp17, sizeof (envOboeFrq17) / sizeof (ENV), envOboeFrq17, sizeof (envOboeAmp18) / sizeof (ENV), envOboeAmp18, sizeof (envOboeFrq18) / sizeof (ENV), envOboeFrq18, sizeof (envOboeAmp19) / sizeof (ENV), envOboeAmp19, sizeof (envOboeFrq19) / sizeof (ENV), envOboeFrq19, sizeof (envOboeAmp20) / sizeof (ENV), envOboeAmp20, sizeof (envOboeFrq20) / sizeof (ENV), envOboeFrq20, sizeof (envOboeAmp21) / sizeof (ENV), envOboeAmp21, sizeof (envOboeFrq21) / sizeof (ENV), envOboeFrq21 } ; //以下定义单簧管的泛音集 PRT prtClar [21] = { sizeof (envClarAmp01) / sizeof (ENV), envClarAmp01, sizeof (envClarFrq01) / sizeof (ENV), envClarFrq01, sizeof (envClarAmp02) / sizeof (ENV), envClarAmp02, sizeof (envClarFrq02) / sizeof (ENV), envClarFrq02, sizeof (envClarAmp03) / sizeof (ENV), envClarAmp03, sizeof (envClarFrq03) / sizeof (ENV), envClarFrq03, sizeof (envClarAmp04) / sizeof (ENV), envClarAmp04, sizeof (envClarFrq04) / sizeof (ENV), envClarFrq04, sizeof (envClarAmp05) / sizeof (ENV), envClarAmp05, sizeof (envClarFrq05) / sizeof (ENV), envClarFrq05, sizeof (envClarAmp06) / sizeof (ENV), envClarAmp06, sizeof (envClarFrq06) / sizeof (ENV), envClarFrq06, sizeof (envClarAmp07) / sizeof (ENV), envClarAmp07, sizeof (envClarFrq07) / sizeof (ENV), envClarFrq07, sizeof (envClarAmp08) / sizeof (ENV), envClarAmp08, sizeof (envClarFrq08) / sizeof (ENV), envClarFrq08, sizeof (envClarAmp09) / sizeof (ENV), envClarAmp09, sizeof (envClarFrq09) / sizeof (ENV), envClarFrq09, sizeof (envClarAmp10) / sizeof (ENV), envClarAmp10, sizeof (envClarFrq10) / sizeof (ENV), envClarFrq10, sizeof (envClarAmp11) / sizeof (ENV), envClarAmp11, sizeof (envClarFrq11) / sizeof (ENV), envClarFrq11, sizeof (envClarAmp12) / sizeof (ENV), envClarAmp12, sizeof (envClarFrq12) / sizeof (ENV), envClarFrq12, sizeof (envClarAmp13) / sizeof (ENV), envClarAmp13, sizeof (envClarFrq13) / sizeof (ENV), envClarFrq13, sizeof (envClarAmp14) / sizeof (ENV), envClarAmp14, sizeof (envClarFrq14) / sizeof (ENV), envClarFrq14, sizeof (envClarAmp15) / sizeof (ENV), envClarAmp15, sizeof (envClarFrq15) / sizeof (ENV), envClarFrq15, sizeof (envClarAmp16) / sizeof (ENV), envClarAmp16, sizeof (envClarFrq16) / sizeof (ENV), envClarFrq16, sizeof (envClarAmp17) / sizeof (ENV), envClarAmp17, sizeof (envClarFrq17) / sizeof (ENV), envClarFrq17, sizeof (envClarAmp18) / sizeof (ENV), envClarAmp18, sizeof (envClarFrq18) / sizeof (ENV), envClarFrq18, sizeof (envClarAmp19) / sizeof (ENV), envClarAmp19, sizeof (envClarFrq19) / sizeof (ENV), envClarFrq19, sizeof (envClarAmp20) / sizeof (ENV), envClarAmp20, sizeof (envClarFrq20) / sizeof (ENV), envClarFrq20, sizeof (envClarAmp21) / sizeof (ENV), envClarAmp21, sizeof (envClarFrq21) / sizeof (ENV), envClarFrq21 } ; INS insTrum = { 360, 12, prtTrum } ;//定义小号的乐器结构并赋值 INS insOboe = { 313, 21, prtOboe } ;//定义双簧管的乐器结构并赋值 INS insClar = { 330, 21, prtClar } ;//定义单簧管的乐器结构并赋值
//resource.h
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 AddSynth.rc 使用 // #define IDC_TRUMPET 1001 #define IDC_OBOE 1002 #define IDC_CLARINET 1003 #define IDC_TEXT 1004 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1005 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
//Addsynth.rc
// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "winres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // 中文(简体,中国) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h " END 2 TEXTINCLUDE BEGIN "#include ""winres.h"" " "