Sinewave Generator

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;
}
}
 
V

Victor Bazarov

NEws said:
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 ?

Does it compile? If yes, does it work [somewhat]? If you
answered 'yes' to both, how can a C++ _language_ newsgroup help?
You apparently don't have a C++ _language_ issue. If you need
help with audio, try a newsgroup that deals with audio, like
comp.games.development.audio or the newsgroup for your OS.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,224
Latest member
BettieToom

Latest Threads

Top