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 =A0could 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
=A0 =A0{
=A0 =A0 char name[2];
=A0 =A0 double frequenz;
=A0 =A0 Uint16 *buffer;
=A0 =A0 int samples, channel_hw,channelonoff; // onoff , -1 on 1.. int
channel=
number depeand on how many channels alloceted
=A0 =A0 Mix_Chunk *play;
=A0 =A0
=A0 =A0
=A0 public:
=A0 =A0 =A0void setbuffer();
=A0 =A0 =A0void setchannel_hw(int ch);
=A0 =A0 =A0int getchannel_hw(){return channel_hw;};
=A0 =A0 =A0void setchannelonoff(int chonoff);
=A0 =A0 =A0int getchannelonoff(){return channelonoff;};
=A0 =A0 =A0
=A0 =A0 =A0Uint16 *getbuffer(){return buffer;};
=A0 =A0 =A0int getsamples(){return samples;};
=A0 =A0 =A0Mix_Chunk *getmixchunk(){return play;};
=A0 =A0 =A0c_Ton(char note[2],double _fr,int _channel,int _chonoff);
=A0 =A0 =A0~c_Ton() {delete buffer;};
};
=A0 =A0 =A0
=A0 =A0 =A0 =A0 =A0 =A0 =A0
Uint16 *make_wave(int _sampling_f,double _frequenz,int &samp,double &f)
=A0 =A0 {
=A0 =A0 =A0 int i,samples;
=A0 =A0 =A0 double freq;
=A0 =A0 =A0 //static int offset;
=A0 =A0 =A0 Uint16 *sine;
=A0 =A0 =A0
=A0 =A0 =A0 =A0samples=3D(int)(_sampling_f/_frequenz);
=A0 =A0 =A0 =A0if (samples%2)
=A0 =A0 =A0 =A0samples++;
=A0 =A0 =A0 =A0
=A0 =A0 =A0 =A0freq=3D_sampling_f/samples;
=A0 =A0 =A0 =A0
=A0 =A0 =A0 =A0sine =3D new Uint16[samples];
=A0 =A0 =A0
=A0 =A0 =A0 for (i=3D0;i<samples;i++)
=A0 =A0 =A0 =A0 =A0{
=A0 =A0 =A0 =A0 =A0
sine[i]=3D(Uint16)(32768+32768*sin(i*2*M_PI*freq/_sampling_f));
=A0 =A0 =A0 =A0 =A0printf("%d \n",sine[i]);
=A0 =A0 =A0 =A0 =A0}
=A0 =A0 =A0 =A0 =A0
=A0 =A0 =A0 =A0 =A0
=A0 =A0 =A0 samp=3Dsamples;
=A0 =A0 =A0 f=3Dfreq;
=A0 =A0 =A0 return sine; =A0 =A0
=A0 =A0 }
void c_Ton::setbuffer()
=A0 =A0{
=A0 =A0int s;
=A0 =A0double f;
=A0 =A0buffer=3Dmake_wave(_SR22050,frequenz,s,f); =A0 =A0 =A0 =A0 =A0 =A0
=A0 =A0 =A0
=A0 =A0samples=3Ds;
=A0 =A0frequenz=3Df;
=A0 =A0}
void c_Ton::setchannel_hw(int ch)
{
=A0 =A0 =A0channel_hw=3Dch;
}
void c_Ton::setchannelonoff(int chonoff)
{
=A0 =A0 =A0channelonoff=3Dchonoff;
}
c_Ton::c_Ton(char note[2],double _frequenz,int _ch_hw,int _chonoff)
{
=A0 =A0strcpy(name,note);
=A0 =A0frequenz=3D_frequenz;
=A0 =A0channel_hw=3D_ch_hw;
=A0 =A0channelonoff=3D_chonoff;// onoff -1 for off 1..int channel number
=A0 =A0setbuffer(); =A0 =A0 =A0 =A0 =A0
=A0 =A0play=3DMix_QuickLoad_RAW((Uint8*)buffer,samples);
}
int phaserChannel =3D -1,phaserChannel2=3D-1,phaserChannel3=3D-1;
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
=A0 =A0 int bpp =3D surface->format->BytesPerPixel;
=A0 =A0 /* Here p is the address to the pixel we want to set */
=A0 =A0 Uint8 *p =3D (Uint8 *)surface->pixels + y * surface->pitch + x *
bpp;
=A0 =A0 switch(bpp) {
=A0 =A0 case 1:
=A0 =A0 =A0 =A0 *p =3D pixel;
=A0 =A0 =A0 =A0 break;
=A0 =A0 case 2:
=A0 =A0 =A0 =A0 *(Uint16 *)p =3D pixel;
=A0 =A0 =A0 =A0 break;
=A0 =A0 case 3:
=A0 =A0 =A0 =A0 if(SDL_BYTEORDER =3D=3D SDL_BIG_ENDIAN) {
=A0 =A0 =A0 =A0 =A0 =A0 p[0] =3D (pixel >>=A016) &=A00xff;
=A0 =A0 =A0 =A0 =A0 =A0 p[1] =3D (pixel >>=A08) &=A00xff;
=A0 =A0 =A0 =A0 =A0 =A0 p[2] =3D pixel &=A00xff;
=A0 =A0 =A0 =A0 } else {
=A0 =A0 =A0 =A0 =A0 =A0 p[0] =3D pixel &=A00xff;
=A0 =A0 =A0 =A0 =A0 =A0 p[1] =3D (pixel >>=A08) &=A00xff;
=A0 =A0 =A0 =A0 =A0 =A0 p[2] =3D (pixel >>=A016) &=A00xff;
=A0 =A0 =A0 =A0 }
=A0 =A0 =A0 =A0 break;
=A0 =A0 case 4:
=A0 =A0 =A0 =A0 *(Uint32 *)p =3D pixel;
=A0 =A0 =A0 =A0 break;
=A0 =A0 }
}
void initvideoaudio(int x,int y)
{
=A0 int audio_rate =3D _SR22050;
=A0 Uint16 audio_format =3D AUDIO_S16;
=A0 int audio_channels =3D 1;
=A0 int audio_buffers =3D 4096;
=A0
=A0
=A0SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
=A0 Mix_OpenAudio(audio_rate, audio_format, audio_channels,
audio_buffers);
=A0 screen =3D SDL_SetVideoMode(x, y, 0, 0);
=A0 Mix_AllocateChannels(90);
=A0
}
int render(int x,int y,int mx) // draw something :-)
{
//int x, y;
Uint32 c,yellow,black;
=A0static int a=3D0;
if (a%2)
c =3D SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
else
c =3D SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
a++;
=A0 =A0
/* Lock the screen for direct access to the pixels */
=A0 =A0 if ( SDL_MUSTLOCK(screen) ) {
=A0 =A0 =A0 =A0 if ( SDL_LockSurface(screen) <=A00 ) {
=A0 =A0 =A0 =A0 =A0 =A0 fprintf(stderr, "Can't lock screen: %s\n",
SDL_GetError());
=A0 =A0 =A0 =A0 =A0 =A0 return 0;
=A0 =A0 =A0 =A0 }
=A0 =A0 }
=A0 =A0
=A0
=A0 =A0 putpixel(screen, x, y, c);
=A0 =A0
=A0 =A0 if ( SDL_MUSTLOCK(screen) ) {
=A0 =A0 =A0 =A0 SDL_UnlockSurface(screen);
=A0 =A0
=A0 =A0
=A0 =A0 }
=A0 =A0 /* Update just the part of the display that we've changed */
=A0 =A0 SDL_UpdateRect(screen, x, y, 1, 1);
=A0
=A0
}
void handleKey(SDL_KeyboardEvent key,c_Ton note);
//c_Ton a("aa",867,1,-1);
int main(int argc, char *argv[]) {
=A0
=A0 initvideoaudio(800,600);
=A0
=A0 int done =3D 0;
=A0
=A0 int i,s,x,t,y;
=A0 //Uint8 *buf;
=A0 //int offset =3D340;
=A0 c_Ton a("aa",200,1,-1);
=A0 //c_Ton b("cc",880,2,-1);
=A0 x =3D 0;
=A0 t=3D0;
=A0 y =3D screen->h / 2;
=A0
=A0 int vilx;
=A0 int maxx;
=A0 vilx=3Dscreen->w/a.getsamples();
=A0 maxx=3Dvilx*a.getsamples();
=A0
printf("M:%d\nS:%d\n",maxx,a.getsamples());
=A0
=A0
=A0 while(!done) {
=A0
=A0 =A0 while(SDL_PollEvent(&event)) {
=A0 =A0 =A0 =A0 switch(event.type) {
=A0 =A0 =A0 =A0 =A0case SDL_QUIT:
=A0 =A0 =A0 =A0 =A0done =3D 1;
=A0 =A0 =A0 =A0 =A0break;
=A0 =A0 =A0
=A0 =A0 =A0 case SDL_KEYDOWN:
=A0 =A0 =A0
=A0 =A0 =A0 case SDL_KEYUP:
=A0 =A0
=A0 =A0 =A0 handleKey(event.key,a);
=A0 =A0
=A0 =A0 =A0 break;
=A0 =A0 =A0
=A0 =A0 =A0 }
=A0 =A0
=A0 =A0 }
=A0 =A0 SDL_Delay(1);
=A0
=A0if(t <=A0a.getsamples()-1 )
=A0 {
=A0 t++;
=A0 }
=A0 else
=A0 t=3D0;
=A0
=A0if (x >=3D maxx)
=A0 {
=A0 x=3D0;
=A0 t=3D0;
}
else
x++;
=A0
y=3Da.getbuffer()[t];
=A0y/=3D1000;
=A0y+=3D300;
// render(x,y,maxx);
//printf ("X:%d Y:%d T:%d\n",x,y,t);
=A0
=A0}
=A0
=A0
=A0 Mix_CloseAudio();
=A0 SDL_Quit();
}
void handleKey(SDL_KeyboardEvent key, c_Ton note)
=A0{
=A0
=A0
=A0
=A0
=A0
=A0
=A0 switch(key.keysym.sym)
=A0 {
=A0 =A0 =A0
=A0 =A0 =A0case SDLK_p:
=A0 =A0 =A0 =A0 =A0 if(key.type =3D=3D SDL_KEYDOWN)
=A0 =A0 =A0 =A0 =A0 =A0{
=A0 =A0 =A0 =A0 =A0 =A0 if(note.getchannelonoff() <=A00)
=A0 =A0 =A0 =A0 =A0 =A0 =A0{
=A0 =A0 =A0 =A0 =A0 =A0=
note.setchannelonoff(Mix_PlayChannel(note.getchannel_hw(),note.getmixchunk(=
), -1));
=A0 =A0 =A0 =A0 =A0 =A0=
//b.setchannelonoff(Mix_PlayChannel(b.getchannel_hw(),b.getmixchunk(),=
-1));
=A0 =A0 =A0 =A0 =A0 =A0 =A0}
=A0 =A0 =A0 =A0
=A0 =A0 =A0 =A0 =A0 =A0}
=A0 =A0 =A0
=A0 =A0 else
=A0 =A0 =A0 {
=A0 =A0 =A0 Mix_HaltChannel(note.getchannelonoff());
=A0 =A0 =A0 note.setchannelonoff(-1);
=A0 =A0 =A0 //Mix_HaltChannel(b.getchannelonoff());
=A0 =A0 =A0 //b.setchannelonoff(-1);
=A0 =A0 =A0
=A0 =A0 =A0
=A0 =A0 =A0 }
=A0 =A0
=A0 =A0
=A0 =A0 break;
=A0 }
}


|