N
NEws
Hi there!
I have a lot of troubles to generate a clean Sine wave and much
more troubles if i try to play more Sine waves at the same time.
I am using the SDL Lib and SDL_Mixer lib.
Here my C++ code could someone give me a hint
why this code is dirty ?
thx
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_mixer.h"
#include <math.h>
#include <conio.h>
#include <string.h>
#define _KAMMERTON 440
#define _HALBTON 1.059463094
#define _SR22050 22050
#define _SR11025 11025
#define _SR44100 44100
SDL_Surface *screen;
SDL_Event event;
class c_Ton
{
char name[2];
double frequenz;
Uint16 *buffer;
int samples, channel_hw,channelonoff; // onoff , -1 on 1.. int channelnumber depeand on how many channels alloceted
Mix_Chunk *play;
public:
void setbuffer();
void setchannel_hw(int ch);
int getchannel_hw(){return channel_hw;};
void setchannelonoff(int chonoff);
int getchannelonoff(){return channelonoff;};
Uint16 *getbuffer(){return buffer;};
int getsamples(){return samples;};
Mix_Chunk *getmixchunk(){return play;};
c_Ton(char note[2],double _fr,int _channel,int _chonoff);
~c_Ton() {delete buffer;};
};
Uint16 *make_wave(int _sampling_f,double _frequenz,int &samp,double &f)
{
int i,samples;
double freq;
//static int offset;
Uint16 *sine;
samples=(int)(_sampling_f/_frequenz);
if (samples%2)
samples++;
freq=_sampling_f/samples;
sine = new Uint16[samples];
for (i=0;i<samples;i++)
{
sine=(Uint16)(32768+32768*sin(i*2*M_PI*freq/_sampling_f));
printf("%d \n",sine);
}
samp=samples;
f=freq;
return sine;
}
void c_Ton::setbuffer()
{
int s;
double f;
buffer=make_wave(_SR22050,frequenz,s,f);
samples=s;
frequenz=f;
}
void c_Ton::setchannel_hw(int ch)
{
channel_hw=ch;
}
void c_Ton::setchannelonoff(int chonoff)
{
channelonoff=chonoff;
}
c_Ton::c_Ton(char note[2],double _frequenz,int _ch_hw,int _chonoff)
{
strcpy(name,note);
frequenz=_frequenz;
channel_hw=_ch_hw;
channelonoff=_chonoff;// onoff -1 for off 1..int channel number
setbuffer();
play=Mix_QuickLoad_RAW((Uint8*)buffer,samples);
}
int phaserChannel = -1,phaserChannel2=-1,phaserChannel3=-1;
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
void initvideoaudio(int x,int y)
{
int audio_rate = _SR22050;
Uint16 audio_format = AUDIO_S16;
int audio_channels = 1;
int audio_buffers = 4096;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers);
screen = SDL_SetVideoMode(x, y, 0, 0);
Mix_AllocateChannels(90);
}
int render(int x,int y,int mx) // draw something
{
//int x, y;
Uint32 c,yellow,black;
static int a=0;
if (a%2)
c = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
else
c = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
a++;
/* Lock the screen for direct access to the pixels */
if ( SDL_MUSTLOCK(screen) ) {
if ( SDL_LockSurface(screen) < 0 ) {
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
return 0;
}
}
putpixel(screen, x, y, c);
if ( SDL_MUSTLOCK(screen) ) {
SDL_UnlockSurface(screen);
}
/* Update just the part of the display that we've changed */
SDL_UpdateRect(screen, x, y, 1, 1);
}
void handleKey(SDL_KeyboardEvent key,c_Ton note);
//c_Ton a("aa",867,1,-1);
int main(int argc, char *argv[]) {
initvideoaudio(800,600);
int done = 0;
int i,s,x,t,y;
//Uint8 *buf;
//int offset =340;
c_Ton a("aa",200,1,-1);
//c_Ton b("cc",880,2,-1);
x = 0;
t=0;
y = screen->h / 2;
int vilx;
int maxx;
vilx=screen->w/a.getsamples();
maxx=vilx*a.getsamples();
printf("M:%d\nS:%d\n",maxx,a.getsamples());
while(!done) {
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
handleKey(event.key,a);
break;
}
}
SDL_Delay(1);
if(t < a.getsamples()-1 )
{
t++;
}
else
t=0;
if (x >= maxx)
{
x=0;
t=0;
}
else
x++;
y=a.getbuffer()[t];
y/=1000;
y+=300;
// render(x,y,maxx);
//printf ("X:%d Y:%d T:%d\n",x,y,t);
}
Mix_CloseAudio();
SDL_Quit();
}
void handleKey(SDL_KeyboardEvent key, c_Ton note)
{
switch(key.keysym.sym)
{
case SDLK_p:
if(key.type == SDL_KEYDOWN)
{
if(note.getchannelonoff() < 0)
{
note.setchannelonoff(Mix_PlayChannel(note.getchannel_hw(),note.getmixchunk(), -1));
//b.setchannelonoff(Mix_PlayChannel(b.getchannel_hw(),b.getmixchunk(),-1));
}
}
else
{
Mix_HaltChannel(note.getchannelonoff());
note.setchannelonoff(-1);
//Mix_HaltChannel(b.getchannelonoff());
//b.setchannelonoff(-1);
}
break;
}
}
I have a lot of troubles to generate a clean Sine wave and much
more troubles if i try to play more Sine waves at the same time.
I am using the SDL Lib and SDL_Mixer lib.
Here my C++ code could someone give me a hint
why this code is dirty ?
thx
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_mixer.h"
#include <math.h>
#include <conio.h>
#include <string.h>
#define _KAMMERTON 440
#define _HALBTON 1.059463094
#define _SR22050 22050
#define _SR11025 11025
#define _SR44100 44100
SDL_Surface *screen;
SDL_Event event;
class c_Ton
{
char name[2];
double frequenz;
Uint16 *buffer;
int samples, channel_hw,channelonoff; // onoff , -1 on 1.. int channelnumber depeand on how many channels alloceted
Mix_Chunk *play;
public:
void setbuffer();
void setchannel_hw(int ch);
int getchannel_hw(){return channel_hw;};
void setchannelonoff(int chonoff);
int getchannelonoff(){return channelonoff;};
Uint16 *getbuffer(){return buffer;};
int getsamples(){return samples;};
Mix_Chunk *getmixchunk(){return play;};
c_Ton(char note[2],double _fr,int _channel,int _chonoff);
~c_Ton() {delete buffer;};
};
Uint16 *make_wave(int _sampling_f,double _frequenz,int &samp,double &f)
{
int i,samples;
double freq;
//static int offset;
Uint16 *sine;
samples=(int)(_sampling_f/_frequenz);
if (samples%2)
samples++;
freq=_sampling_f/samples;
sine = new Uint16[samples];
for (i=0;i<samples;i++)
{
sine=(Uint16)(32768+32768*sin(i*2*M_PI*freq/_sampling_f));
printf("%d \n",sine);
}
samp=samples;
f=freq;
return sine;
}
void c_Ton::setbuffer()
{
int s;
double f;
buffer=make_wave(_SR22050,frequenz,s,f);
samples=s;
frequenz=f;
}
void c_Ton::setchannel_hw(int ch)
{
channel_hw=ch;
}
void c_Ton::setchannelonoff(int chonoff)
{
channelonoff=chonoff;
}
c_Ton::c_Ton(char note[2],double _frequenz,int _ch_hw,int _chonoff)
{
strcpy(name,note);
frequenz=_frequenz;
channel_hw=_ch_hw;
channelonoff=_chonoff;// onoff -1 for off 1..int channel number
setbuffer();
play=Mix_QuickLoad_RAW((Uint8*)buffer,samples);
}
int phaserChannel = -1,phaserChannel2=-1,phaserChannel3=-1;
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
void initvideoaudio(int x,int y)
{
int audio_rate = _SR22050;
Uint16 audio_format = AUDIO_S16;
int audio_channels = 1;
int audio_buffers = 4096;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers);
screen = SDL_SetVideoMode(x, y, 0, 0);
Mix_AllocateChannels(90);
}
int render(int x,int y,int mx) // draw something
{
//int x, y;
Uint32 c,yellow,black;
static int a=0;
if (a%2)
c = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
else
c = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
a++;
/* Lock the screen for direct access to the pixels */
if ( SDL_MUSTLOCK(screen) ) {
if ( SDL_LockSurface(screen) < 0 ) {
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
return 0;
}
}
putpixel(screen, x, y, c);
if ( SDL_MUSTLOCK(screen) ) {
SDL_UnlockSurface(screen);
}
/* Update just the part of the display that we've changed */
SDL_UpdateRect(screen, x, y, 1, 1);
}
void handleKey(SDL_KeyboardEvent key,c_Ton note);
//c_Ton a("aa",867,1,-1);
int main(int argc, char *argv[]) {
initvideoaudio(800,600);
int done = 0;
int i,s,x,t,y;
//Uint8 *buf;
//int offset =340;
c_Ton a("aa",200,1,-1);
//c_Ton b("cc",880,2,-1);
x = 0;
t=0;
y = screen->h / 2;
int vilx;
int maxx;
vilx=screen->w/a.getsamples();
maxx=vilx*a.getsamples();
printf("M:%d\nS:%d\n",maxx,a.getsamples());
while(!done) {
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
handleKey(event.key,a);
break;
}
}
SDL_Delay(1);
if(t < a.getsamples()-1 )
{
t++;
}
else
t=0;
if (x >= maxx)
{
x=0;
t=0;
}
else
x++;
y=a.getbuffer()[t];
y/=1000;
y+=300;
// render(x,y,maxx);
//printf ("X:%d Y:%d T:%d\n",x,y,t);
}
Mix_CloseAudio();
SDL_Quit();
}
void handleKey(SDL_KeyboardEvent key, c_Ton note)
{
switch(key.keysym.sym)
{
case SDLK_p:
if(key.type == SDL_KEYDOWN)
{
if(note.getchannelonoff() < 0)
{
note.setchannelonoff(Mix_PlayChannel(note.getchannel_hw(),note.getmixchunk(), -1));
//b.setchannelonoff(Mix_PlayChannel(b.getchannel_hw(),b.getmixchunk(),-1));
}
}
else
{
Mix_HaltChannel(note.getchannelonoff());
note.setchannelonoff(-1);
//Mix_HaltChannel(b.getchannelonoff());
//b.setchannelonoff(-1);
}
break;
}
}