mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-03-02 21:45:25 +00:00
git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@816 6778bc44-b910-0410-a7a0-be141de4315d
408 lines
9.6 KiB
C++
408 lines
9.6 KiB
C++
/**
|
|
* projectM -- Milkdrop-esque visualisation SDK
|
|
* Copyright (C)2003-2004 projectM Team
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
* See 'LICENSE.txt' included within this release
|
|
*
|
|
*/
|
|
#include "video_init.h"
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <SDL/SDL.h>
|
|
#include <projectM.hpp>
|
|
#include "sdltoprojectM.h"
|
|
|
|
#include "ConfigFile.h"
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
#include <jack/jack.h>
|
|
|
|
#define CONFIG_FILE "/share/projectM/config.inp"
|
|
|
|
std::string read_config();
|
|
|
|
jack_port_t *input_port;
|
|
jack_client_t *client;
|
|
jack_default_audio_sample_t out[1024*1000];
|
|
|
|
#ifdef DEBUG
|
|
FILE *debugFile = NULL;
|
|
#endif
|
|
|
|
volatile enum client_state_t {
|
|
Init,
|
|
Run,
|
|
Exit
|
|
} client_state = Init;
|
|
|
|
SDL_Surface *screen;
|
|
|
|
projectM *globalPM = NULL;
|
|
|
|
int dumpFrame = 0;
|
|
int frameNumber = 0;
|
|
|
|
|
|
int texsize=512;
|
|
int gx=32,gy=24;
|
|
int wvw=512,wvh=512;
|
|
int fvw=1024,fvh=768;
|
|
int fps=30, fullscreen=0;
|
|
|
|
|
|
|
|
|
|
std::string read_config()
|
|
{
|
|
|
|
int n;
|
|
|
|
char num[512];
|
|
FILE *in;
|
|
FILE *out;
|
|
|
|
char* home;
|
|
char projectM_home[1024];
|
|
char projectM_config[1024];
|
|
|
|
strcpy(projectM_config, PROJECTM_PREFIX);
|
|
strcpy(projectM_config+strlen(PROJECTM_PREFIX), CONFIG_FILE);
|
|
projectM_config[strlen(PROJECTM_PREFIX)+strlen(CONFIG_FILE)]='\0';
|
|
printf("dir:%s \n",projectM_config);
|
|
home=getenv("HOME");
|
|
strcpy(projectM_home, home);
|
|
strcpy(projectM_home+strlen(home), "/.projectM/config.inp");
|
|
projectM_home[strlen(home)+strlen("/.projectM/config.inp")]='\0';
|
|
|
|
|
|
if ((in = fopen(projectM_home, "r")) != 0)
|
|
{
|
|
printf("reading ~/.projectM/config.inp \n");
|
|
fclose(in);
|
|
return std::string(projectM_home);
|
|
}
|
|
else
|
|
{
|
|
printf("trying to create ~/.projectM/config.inp \n");
|
|
|
|
strcpy(projectM_home, home);
|
|
strcpy(projectM_home+strlen(home), "/.projectM");
|
|
projectM_home[strlen(home)+strlen("/.projectM")]='\0';
|
|
mkdir(projectM_home,0755);
|
|
|
|
strcpy(projectM_home, home);
|
|
strcpy(projectM_home+strlen(home), "/.projectM/config.inp");
|
|
projectM_home[strlen(home)+strlen("/.projectM/config.inp")]='\0';
|
|
|
|
if((out = fopen(projectM_home,"w"))!=0)
|
|
{
|
|
|
|
if ((in = fopen(projectM_config, "r")) != 0)
|
|
{
|
|
|
|
while(fgets(num,80,in)!=NULL)
|
|
{
|
|
fputs(num,out);
|
|
}
|
|
fclose(in);
|
|
fclose(out);
|
|
|
|
|
|
if ((in = fopen(projectM_home, "r")) != 0)
|
|
{
|
|
printf("created ~/.projectM/config.inp successfully\n");
|
|
fclose(in);
|
|
return std::string(projectM_home);
|
|
}
|
|
else{printf("This shouldn't happen, using implementation defualts\n");abort();}
|
|
}
|
|
else{printf("Cannot find projectM default config, using implementation defaults\n");abort();}
|
|
}
|
|
else
|
|
{
|
|
printf("Cannot create ~/.projectM/config.inp, using default config file\n");
|
|
if ((in = fopen(projectM_config, "r")) != 0)
|
|
{ printf("Successfully opened default config file\n");
|
|
fclose(in);
|
|
return std::string(projectM_config);}
|
|
else{ printf("Using implementation defaults, your system is really messed up, I'm suprised we even got this far\n"); abort();}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
abort();
|
|
}
|
|
|
|
void renderLoop() {
|
|
|
|
int i;
|
|
int x, y;
|
|
int index;
|
|
short pcm_data[2][512];
|
|
|
|
while ( 1 ) {
|
|
projectMEvent evt;
|
|
projectMKeycode key;
|
|
projectMModifier mod;
|
|
|
|
/** Process SDL events */
|
|
SDL_Event event;
|
|
while ( SDL_PollEvent( &event ) ) {
|
|
/** Translate into projectM codes and process */
|
|
evt = sdl2pmEvent( event );
|
|
key = sdl2pmKeycode( event.key.keysym.sym );
|
|
mod = sdl2pmModifier( event.key.keysym.mod );
|
|
|
|
if ( evt == PROJECTM_KEYDOWN ) {
|
|
|
|
|
|
if(key == PROJECTM_K_f)
|
|
{
|
|
if (++fullscreen%2)
|
|
{
|
|
resize_display(fvw, fvh, fullscreen%2);
|
|
globalPM->projectM_resetGL( fvw, fvh );
|
|
}
|
|
else
|
|
{
|
|
resize_display(wvw, wvh, fullscreen%2);
|
|
globalPM->projectM_resetGL( wvw, wvh );
|
|
}
|
|
}
|
|
else if(key == PROJECTM_K_q || key == PROJECTM_K_ESCAPE) {delete(globalPM); exit (1);}
|
|
else {globalPM->key_handler(evt,key,mod);}
|
|
|
|
}
|
|
else if ( evt == PROJECTM_VIDEORESIZE )
|
|
{
|
|
wvw=event.resize.w;
|
|
wvh=event.resize.h;
|
|
resize_display(wvw, wvh, fullscreen%2);
|
|
globalPM->projectM_resetGL( wvw, wvh );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Render the new frame */
|
|
globalPM->renderFrame( );
|
|
|
|
|
|
SDL_GL_SwapBuffers();
|
|
}
|
|
|
|
printf("Worker thread: Exiting\n");
|
|
}
|
|
|
|
int
|
|
process (jack_nframes_t nframes, void *arg)
|
|
{
|
|
jack_default_audio_sample_t *in;
|
|
jack_transport_state_t ts = jack_transport_query(client, NULL);
|
|
|
|
if (ts == JackTransportRolling) {
|
|
|
|
if (client_state == Init)
|
|
client_state = Run;
|
|
|
|
in = (jack_default_audio_sample_t*)jack_port_get_buffer (input_port, nframes);
|
|
|
|
//memcpy (out, in,sizeof (jack_default_audio_sample_t) * nframes);
|
|
|
|
globalPM->pcm()->addPCMfloat(in,nframes);
|
|
//printf("%x %f\n",nframes,in[128]);
|
|
|
|
|
|
} else if (ts == JackTransportStopped) {
|
|
|
|
if (client_state == Run)
|
|
client_state = Exit;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void jack_shutdown (void *arg)
|
|
{
|
|
exit (1);
|
|
}
|
|
|
|
int main( int argc, char **argv ) {
|
|
const char **ports;
|
|
const char *client_name;
|
|
const char *server_name = NULL;
|
|
jack_options_t options = JackNullOption;
|
|
jack_status_t status;
|
|
int i;
|
|
char projectM_data[1024];
|
|
|
|
|
|
std::string config_file;
|
|
config_file = read_config();
|
|
|
|
ConfigFile config(config_file);
|
|
|
|
wvw = config.read<int>( "Window Width", 512 );
|
|
wvh = config.read<int>( "Window Height", 512 );
|
|
int fullscreen = 0;
|
|
if (config.read("Fullscreen", true)) fullscreen = 1;
|
|
else fullscreen = 0;
|
|
|
|
|
|
#ifdef DEBUG
|
|
int value;
|
|
int rgb_size[3];
|
|
#endif
|
|
|
|
const SDL_VideoInfo* info = NULL;
|
|
int bpp = 0;
|
|
/* Flags we will pass into SDL_SetVideoMode. */
|
|
int flags = 0;
|
|
|
|
//JACK INIT
|
|
//----------------------------------------------
|
|
if (argc >= 2) { /* client name specified? */
|
|
client_name = argv[1];
|
|
if (argc >= 3) { /* server name specified? */
|
|
server_name = argv[2];
|
|
// options |= JackServerName;
|
|
}
|
|
} else { /* use basename of argv[0] */
|
|
client_name = strrchr(argv[0], '/');
|
|
if (client_name == 0) {
|
|
client_name = argv[0];
|
|
} else {
|
|
client_name++;
|
|
}
|
|
}
|
|
|
|
/* open a client connection to the JACK server */
|
|
|
|
client = jack_client_open (client_name, options, &status, server_name);
|
|
if (client == NULL) {
|
|
fprintf (stderr, "jack_client_open() failed, "
|
|
"status = 0x%2.0x\n", status);
|
|
if (status & JackServerFailed) {
|
|
fprintf (stderr, "Unable to connect to JACK server\n");
|
|
}
|
|
exit (1);
|
|
}
|
|
if (status & JackServerStarted) {
|
|
fprintf (stderr, "JACK server started\n");
|
|
}
|
|
if (status & JackNameNotUnique) {
|
|
client_name = jack_get_client_name(client);
|
|
fprintf (stderr, "unique name `%s' assigned\n", client_name);
|
|
}
|
|
|
|
/* tell the JACK server to call `process()' whenever
|
|
there is work to be done.
|
|
*/
|
|
|
|
jack_set_process_callback (client, process, 0);
|
|
|
|
/* tell the JACK server to call `jack_shutdown()' if
|
|
it ever shuts down, either entirely, or if it
|
|
just decides to stop calling us.
|
|
*/
|
|
|
|
jack_on_shutdown (client, jack_shutdown, 0);
|
|
|
|
/* display the current sample rate.
|
|
*/
|
|
|
|
printf ("engine sample rate: %d\n",
|
|
jack_get_sample_rate (client));
|
|
|
|
/* create two ports */
|
|
|
|
input_port = jack_port_register (client, "input",
|
|
JACK_DEFAULT_AUDIO_TYPE,
|
|
JackPortIsInput, 0);
|
|
|
|
if (input_port == NULL) {
|
|
fprintf(stderr, "no more JACK ports available\n");
|
|
exit (1);
|
|
}
|
|
|
|
/* Tell the JACK server that we are ready to roll. Our
|
|
* process() callback will start running now. */
|
|
|
|
|
|
|
|
//END JACK INIT ----------------------------------
|
|
init_display(wvw,wvh,&fvw,&fvh,fullscreen);
|
|
/** Setup some window stuff */
|
|
SDL_WM_SetCaption( PROJECTM_TITLE, NULL );
|
|
globalPM = new projectM(config_file);
|
|
/** Initialise projectM */
|
|
|
|
|
|
|
|
|
|
//JACK BEGIN-----------------------------
|
|
|
|
if (jack_activate (client)) {
|
|
fprintf (stderr, "cannot activate client");
|
|
exit (1);
|
|
}
|
|
|
|
/* Connect the ports. You can't do this before the client is
|
|
* activated, because we can't make connections to clients
|
|
* that aren't running. Note the confusing (but necessary)
|
|
* orientation of the driver backend ports: playback ports are
|
|
* "input" to the backend, and capture ports are "output" from
|
|
* it.
|
|
*/
|
|
|
|
ports = jack_get_ports (client, NULL, NULL, JackPortIsOutput);
|
|
if (ports == NULL) {
|
|
fprintf(stderr, "no physical capture ports\n");
|
|
exit (1);
|
|
}
|
|
|
|
|
|
i=0;
|
|
while (ports[i]!=NULL)
|
|
{
|
|
printf("Connecting to Jack port %s\n",ports[i]);
|
|
if (jack_connect (client, ports[i], jack_port_name (input_port))) {
|
|
fprintf (stderr, "cannot connect input ports\n");
|
|
}
|
|
i++;
|
|
}
|
|
|
|
free (ports);
|
|
|
|
//----------------------------------END
|
|
|
|
|
|
/** Initialise the thread */
|
|
renderLoop();
|
|
|
|
return 1;
|
|
}
|
|
|
|
|