Ok here's an update, I did figure out how to do this and since this thread is still active I'll post my code for everyone else. This works for me on any machine I try it on...
This is a "bare-bone" version of my further developed app, in this source I included my FFT algorithm, which is rendered by opengl obviously.
I probably did a lot of stupid things, I don't know, I'm teaching myself everything from the OpenAL specification and programming guide. Everything else I've had to figure out too since I can't freaking get much help since everything I say to anyone is misunderstood. So if you see anything I did that was dumb please tell me and why so I can better understand.
Thanks! and hope this helps someone else out there wanting code like this.
Just fyi, I have A LOT of problems getting this code to work in VISTA, apparently since they removed HAL a lot of stuff is screwed up and I need to get a new sound card or something to get openal code working right...
The signal always seems impossibly low... anyone have any insight in to this? Damn it vista....
Btw I already know the line with "bval = (ALint)(((ALint *)mybuf)[i]/32768.0) / (float)lval;" is a very wrong way of getting that value.... lol I'm working on that part still, it seems to work for the time being.
#include <math.h>
#include <vector>
#include <GL/glut.h>
#include <AL/al.h>
#include <AL/alc.h>
#define SRATE 44100
#define BUF 1024
#define PI 3.1415
using namespace std;
ALCdevice *mydevice;
ALbyte mybuf[SRATE];
ALint samples;
int lval=32768;
int samplesize = (int)(BUF);
int x=0, i=0;
float fx=0.0, fy=0.0, bval=0.0;
// APP
float _x(float n)
{
return (n/480.0f);
}
float _y(float n)
{
return (n/240.0f);
}
vector<float> fft (vector<float> w)
{
vector<float>
Samples, Im, Re;
int N=w.size(), L=(int)(N/2.0f), j=0, k=0;
float fIm=0.0, fRe=0.0, ft=0.0;
for (k=0; k<L; k++)
{
Im.push_back(w.at(k*2));
Re.push_back(w.at((k*2)+1));
}
for (j=0; j<N; j++)
{
fIm = 0.0;
fRe = 0.0;
for (k=0; k<L; k++)
{
fIm += Im.at(k) * sin(2*PI*j*k/N);
fRe += Re.at(k) * cos(2*PI*j*k/N);
}
ft = sqrt(fIm*fIm+fRe*fRe);
Samples.push_back(ft);
}
return Samples;
}
/* GLUT callback Handlers */
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
static void display(void)
{
vector<float> cvals, fvals;
alcGetIntegerv(mydevice, ALC_CAPTURE_SAMPLES, (ALCsizei)sizeof(ALint), &samples);
alcCaptureSamples(mydevice, (ALCvoid *)mybuf, samples);
for (i=0; i<samplesize; i++)
{
bval = (ALint)(((ALint *)mybuf)[i]/32768.0) / (float)lval;
cvals.push_back( bval );
}
for (i=0; i<(samplesize/4.0); i++)
{
fvals.push_back(cvals.at(i));
}
fvals = fft(fvals);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0,0.0,0.0);
glPushMatrix();
glBegin(GL_LINE_STRIP);
for (x=0; x<cvals.size(); x++)
{
fx = _x((float)x) - 2.0f;
fy = (cvals.at(x)/2.0f) - 0.5f;
glVertex3f(fx, fy, -3.0f);
}
glEnd();
glBegin(GL_LINE_STRIP);
for (x=0; x<fvals.size(); x++)
{
fx = _x((float)x) - 0.5f;
fy = (fvals.at(x)/(fvals.size()/8.0f)) + 0.5f;
glVertex3f(fx, fy, -3.0f);
}
glEnd();
glPopMatrix();
glutSwapBuffers();
}
static void key(unsigned char key, int x, int y)
{
switch (key)
{
case 'q':
exit(0);
break;
}
glutPostRedisplay();
}
static void idle(void)
{
glutPostRedisplay();
}
/* Program entry point */
int main(int argc, char *argv[])
{
alGetError();
mydevice = alcCaptureOpenDevice(NULL, SRATE, AL_FORMAT_STEREO16, BUF);
if (alGetError() != AL_NO_ERROR)
{
return 0;
}
alcCaptureStart(mydevice);
glutInit(&argc, argv);
glutInitWindowSize(480,240);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("fftaudio-");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glClearColor(1,1,1,1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glutMainLoop();
alcCaptureStop(mydevice);
alcCaptureCloseDevice(mydevice);
return EXIT_SUCCESS;
}