音色合成器

#include <stdio.h>
#include <iostream>
#include <graphics.h>
#include <math.h>
#include <mmsystem.h>
#define M_PI 3.1415926535
#define fm(fa,fb,va,vb,x) (va*sin(x*fa*M_PI/10000.0+vb*sin(x*fb*M_PI/10000.0)))
using namespace std;
const int w = 640,h = 480;
class pcmplay {
	private:
		HWAVEOUT        hwo;
		WAVEHDR         wh;
		WAVEFORMATEX    wfx;
		HANDLE          wait;
	public:
		void initpcmout() {
			wfx.wFormatTag = WAVE_FORMAT_PCM;
			wfx.nChannels = 1;
			wfx.nSamplesPerSec = 8000;
			wfx.nAvgBytesPerSec = 16000;
			wfx.nBlockAlign = 2;
			wfx.wBitsPerSample = 16;
			wfx.cbSize = 0;
		}
		void play(char *buf,size_t bufsiz) {
			wait = CreateEvent(NULL, 0, 0, NULL);
			waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);
			wh.lpData = buf;
			wh.dwBufferLength = bufsiz;
			wh.dwFlags = 0L;
			wh.dwLoops = 1L;
			waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR));
			waveOutWrite(hwo, &wh, sizeof(WAVEHDR));
			WaitForSingleObject(wait, INFINITE);
		}
		void end() {
			//waveOutClose(hwo);
			waveOutReset(hwo);
		}
};
const int buflen = 1024*320;
pcmplay outwav;
double fa=1000,fb=1000,va=120,vb=120;
/*
~=va*sin(x*fa+vb*sin(x*fb))
+----------+ | +----------+   0,16  255,16
+----------+ | +----------+
             |
+----------+ | +----------+
+----------+ | +----------+
         |==play==|
*/
void linebar(int x1,int y1,int x2,int y2) {
	line (x1,y1,x2,y1);
	line (x1,y1,x1,y2);
	line (x2,y2,x2,y1);
	line (x2,y2,x1,y2);
}
int main() {
	outwav.initpcmout();//init
	setinitmode (2);
	initgraph(w,h);
	setfont(16,8,"宋体");
	MOUSEMSG msg;
	int ldown=0,isplay = 1;
	char *buf = new char[buflen];
	for (;; delay_fps(60)) {
		cleardevice ();
		setcolor (0x00ff00);
		xyprintf (0,0,"fm合成器  va*sin(x*fa+vb*sin(x*fb)):");
		setcolor (0x777777);
		xyprintf (0,32,"va(0-255):%.5f",va*2.0);
		xyprintf (288,32,"vb(0-255):%.5f",vb*2.0);
		xyprintf (0,56,"fa(0-4095):%.5f",fa);
		xyprintf (288,56,"fb(0-4095):%.5f",fb);
		setcolor (0x22ff55);
		linebar(0,32,256,48);
		linebar(0,56,256,72);
		linebar(288,32,288+256,48);
		linebar(288,56,288+256,72);
		setcolor (0xffff00);
		line (va*2,32,va*2,48);
		line (fa/16,56,fa/16,72);
		line (288+vb*2,32,288+vb*2,48);
		line (288+fb/16,56,288+fb/16,72);
		xyprintf (0,h-16,"fps:%.5f   FMake by gy134",getfps());
		for (int i = 0; i <= w; ++i)
			buf[i] = (char)fm(fa,fb,va,vb,i);
		for (int i = 0; i <= w; ++i)
			putpixel(i,h-128-16+buf[i],0xffffff);
		while (mousemsg()) {
			msg = GetMouseMsg();
			if (msg.uMsg == 513)
				ldown = 1;
			if (msg.uMsg == 514) {
				ldown = 0;
				if (isplay == 1) {
					for (int i = 0; i < buflen; ++i)
						buf[i] = (char)fm(fa,fb,va,vb,i);
					outwav.end();
					outwav.play(buf,buflen);//play
				}
			}
		}
		if (ldown == 1) {
			if (msg.x >= 0&&msg.x <= 255&&msg.y > 32&&msg.y < 48)
				va = msg.x/2.0;
			if (msg.x >= 0&&msg.x <= 255&&msg.y > 56&&msg.y < 72)
				fa = 16*msg.x;
			if (msg.x >= 288&&msg.x <= 288+255&&msg.y > 32&&msg.y < 48)
				vb = (msg.x-288)/2.0;
			if (msg.x >= 288&&msg.x <= 288+255&&msg.y > 56&&msg.y < 72)
				fb = 16*(msg.x-288);
		}
		while (kbhit())
			if (getch() == 13)isplay = !isplay;
		if (isplay == 0)outwav.end();
	}
}
/*FMake by gy314*/
#include <stdio.h>
#include <iostream>
#include <graphics.h>
#include <math.h>
#include <mmsystem.h>
#define M_PI 3.1415926535
#define am(fa,fb,va,vb,x) ((va*sin(x*fa*M_PI/10000.0))*(vb*sin(x*fb*M_PI/10000.0)))
using namespace std;
const int w = 640,h = 480;
class pcmplay {
	private:
		HWAVEOUT        hwo;
		WAVEHDR         wh;
		WAVEFORMATEX    wfx;
		HANDLE          wait;
	public:
		void initpcmout() {
			wfx.wFormatTag = WAVE_FORMAT_PCM;
			wfx.nChannels = 1;
			wfx.nSamplesPerSec = 8000;
			wfx.nAvgBytesPerSec = 16000;
			wfx.nBlockAlign = 2;
			wfx.wBitsPerSample = 16;
			wfx.cbSize = 0;
		}
		void play(char *buf,size_t bufsiz) {
			wait = CreateEvent(NULL, 0, 0, NULL);
			waveOutOpen(&hwo, WAVE_MAPPER, &wfx, (DWORD_PTR)wait, 0L, CALLBACK_EVENT);
			wh.lpData = buf;
			wh.dwBufferLength = bufsiz;
			wh.dwFlags = 0L;
			wh.dwLoops = 1L;
			waveOutPrepareHeader(hwo, &wh, sizeof(WAVEHDR));
			waveOutWrite(hwo, &wh, sizeof(WAVEHDR));
			WaitForSingleObject(wait, INFINITE);
		}
		void end() {
			//waveOutClose(hwo);
			waveOutReset(hwo);
		}
};
const int buflen = 1024*320;
pcmplay outwav;
double fa=1000,fb=1000,va=120,vb=120;
/*
~=va*sin(x*fa+vb*sin(x*fb))
+----------+ | +----------+   0,16  255,16
+----------+ | +----------+
             |
+----------+ | +----------+
+----------+ | +----------+
         |==play==|
*/
void linebar(int x1,int y1,int x2,int y2) {
	line (x1,y1,x2,y1);
	line (x1,y1,x1,y2);
	line (x2,y2,x2,y1);
	line (x2,y2,x1,y2);
}
int main() {
	outwav.initpcmout();//init
	setinitmode (2);
	initgraph(w,h);
	setfont(16,8,"宋体");
	MOUSEMSG msg;
	int ldown=0,isplay = 1;
	char *buf = new char[buflen];
	for (;; delay_fps(60)) {
		cleardevice ();
		setcolor (0x00ff00);
		xyprintf (0,0,"am合成器  (va*sin(x*fa))*(vb*sin(x*fb)):");
		setcolor (0x777777);
		xyprintf (0,32,"va(0-255):%.5f",va*2.0);
		xyprintf (288,32,"vb(0-255):%.5f",vb*2.0);
		xyprintf (0,56,"fa(0-4095):%.5f",fa);
		xyprintf (288,56,"fb(0-4095):%.5f",fb);
		setcolor (0x22ff55);
		linebar(0,32,256,48);
		linebar(0,56,256,72);
		linebar(288,32,288+256,48);
		linebar(288,56,288+256,72);
		setcolor (0xffff00);
		line (va*2,32,va*2,48);
		line (fa/16,56,fa/16,72);
		line (288+vb*2,32,288+vb*2,48);
		line (288+fb/16,56,288+fb/16,72);
		xyprintf (0,h-16,"fps:%.5f   AMake by gy134",getfps());
		for (int i = 0; i <= w; ++i)
			buf[i] = (char)am(fa,fb,va,vb,i);
		for (int i = 0; i <= w; ++i)
			putpixel(i,h-128-16+buf[i],0xffffff);
		while (mousemsg()) {
			msg = GetMouseMsg();
			if (msg.uMsg == 513)
				ldown = 1;
			if (msg.uMsg == 514) {
				ldown = 0;
				if (isplay == 1) {
					for (int i = 0; i < buflen; ++i)
						buf[i] = (char)am(fa,fb,va,vb,i);
					outwav.end();
					outwav.play(buf,buflen);//play
				}
			}
		}
		if (ldown == 1) {
			if (msg.x >= 0&&msg.x <= 255&&msg.y > 32&&msg.y < 48)
				va = msg.x/2.0;
			if (msg.x >= 0&&msg.x <= 255&&msg.y > 56&&msg.y < 72)
				fa = 16*msg.x;
			if (msg.x >= 288&&msg.x <= 288+255&&msg.y > 32&&msg.y < 48)
				vb = (msg.x-288)/2.0;
			if (msg.x >= 288&&msg.x <= 288+255&&msg.y > 56&&msg.y < 72)
				fb = 16*(msg.x-288);
		}
		while (kbhit())
			if (getch() == 13)isplay = !isplay;
		if (isplay == 0)outwav.end();
	}
}
/*AMake by gy314*/


评论区