Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
soundserver.segfault.cpp
Go to the documentation of this file.
1 int GetMaxVolume();
2 #include "lin_time.h"
3 #ifdef __APPLE__
4 #include <sys/types.h>
5 #include <pwd.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <fcntl.h>
9 extern "C" {
10 #include "../fmod.h"
11 #include <mach/thread_policy.h>
12 #include <mach/mach_init.h>
13 
14 #ifdef __MACH__
15 kern_return_t thread_policy_set( thread_act_t thread, natural_t flavor, thread_policy_t policy_info, natural_t count );
16 mach_port_t mach_thread_self( void );
17 #endif
18 }
19 
20 #include <queue>
21 #include <list>
22 using std::list;
23 using std::queue;
24 bool e_already_sent = false;
25 void music_finished();
26 signed char endcallback( FSOUND_STREAM *stream, void *buf, int len, int param )
27 {
28  if (!buf)
30  return 0;
31 }
32 struct Music
33 {
34  FSOUND_STREAM *m;
35  int channel;
36  Music()
37  {
38  m = NULL;
39  channel = 0;
40  }
41  void Stop()
42  {
43  if (m) FSOUND_Stream_Stop( m );
44  }
45  void Free()
46  {
47  if (m) {
48  const float ram_limit = 47;
49  static list< FSOUND_STREAM* >q;
50  q.push_back( m );
51  if (q.size() > ram_limit) {
52  FSOUND_Stream_Close( q.front() );
53  q.pop_front();
54  }
55  }
56  m = NULL;
57  }
58  bool Load( const char *file )
59  {
60  m = FSOUND_Stream_OpenFile( file, FSOUND_NORMAL|FSOUND_MPEGACCURATE, 0 );
61  return true;
62  }
63  /*
64  *
65  * void Play(float fadeout, float fadein, Music &oldmusic){
66  * if (!m) return;
67  * FSOUND_Stream_SetEndCallback(m,endcallback,0);
68  * channel = FSOUND_Stream_PlayEx(FSOUND_FREE, m, NULL, 1);
69  * SetVolume(0);
70  * FSOUND_SetPaused(channel, 0);
71  * if (fadeout*100>1) {
72  * for (unsigned int i=0;i<fadeout*100;i++) {
73  * SetVolume(i/(float)fadeout);
74  * oldmusic.SetVolume(((float)fadeout-i)/fadeout);
75  * micro_sleep (10000);
76  * }
77  * }
78  * SetVolume(1);
79  * oldmusic.Stop();
80  * }
81  * void SetVolume(float vol) {
82  * if (m) {
83  * F_API FSOUND_SetVolume(this->channel,(int)(vol*GetMaxVolume()));
84  * }
85  * }
86  * void SetMasterVolume(float vol) {
87  * FSOUND_SetSFXMasterVolume((int) (vol*GetMaxVolume()));
88  * }
89  */
90  void Play( float fadeout, float fadein, Music &oldmusic )
91  {
92  if (!m) return;
93  if (fadeout) {
94  FSOUND_Stream_SetEndCallback( m, endcallback, 0 );
95  FSOUND_Stream_SetSynchCallback( m, endcallback, 0 );
96  channel = FSOUND_Stream_Play( FSOUND_FREE, m );
97  if (!e_already_sent) {
98  SetVolume( 0 );
99  if (fadeout*10 > 1)
100  for (unsigned int i = 0; i < fadeout*10; i++) {
101  float ratio = ( (float) i )/(fadeout*10.);
102  SetVolume( ratio );
103  if (!e_already_sent)
104  oldmusic.SetVolume( 1-ratio );
105  micro_sleep( 10000 );
106  }
107  if (!e_already_sent) //race condition I know I know--not much we can do bout it..besides this ole girl crashes when she wishes.
108  oldmusic.Stop();
109  }
110  } else if (!e_already_sent) {
111  oldmusic.Stop();
112  }
113  oldmusic.Free();
114  if (!fadeout) {
115  FSOUND_Stream_SetEndCallback( m, endcallback, 0 );
116  channel = FSOUND_Stream_Play( FSOUND_FREE, m );
117  }
118  SetVolume( 1 );
119  e_already_sent = false;
120  }
121  void SetMasterVolume( float vol )
122  {
123  FSOUND_SetSFXMasterVolume( (int) ( vol*GetMaxVolume() ) );
124  }
125  void SetVolume( float vol )
126  {
127  if (m)
128  //printf ("Setting %d to %d\n", this->channel, (int)(vol*GetMaxVolume()));
129  F_API FSOUND_SetVolume( this->channel, (int) ( vol*GetMaxVolume() ) );
130  }
131 };
132 #else
133 #define HAVE_SDL
134 #ifdef HAVE_SDL
135 #include <SDL/SDL.h>
136 #include <SDL/SDL_thread.h>
137 #include <SDL/SDL_mixer.h>
138 #else
139 typedef int Mix_Music;
140 #endif
141 struct Music
142 {
143  Mix_Music *m;
145  {
146  m = NULL;
147  }
148  bool Load( const char *file )
149  {
150  m = Mix_LoadMUS( file );
151  return m != NULL;
152  }
153  bool Play( float fadeout, float fadein, Music &oldmusic )
154  {
155  if (m) {
156  int fadesteps = fadeout*100;
157  for (int i = fadesteps; i >= 0; i--) {
158  oldmusic.SetVolume( i/(float) fadesteps );
159  micro_sleep( 10000 );
160  }
161  Mix_FadeInMusic( m, 1, fadein ) != -1;
162  micro_sleep( fadein*1000000 );
163 
164  return true;
165  } else {
166  return false;
167  }
168  }
169  void Stop()
170  {
171  if (m) Mix_StopMusic( m );
172  }
173  void Free()
174  {
175  if (m) Mix_FreeMusic( m );
176  }
177  void SetVolume( float vol )
178  {
179  if (m)
180  Mix_VolumeMusic( vol*GetMaxVolume() );
181  }
182  void SetMasterVolume( float vol )
183  {
184  SetVolume( vol );
185  }
186 }
187 #ifdef _WIN32
188 #ifndef NOMINMAX
189 #define NOMINMAX
190 #endif //tells VCC not to generate min/max macros
191 #include <direct.h>
192 #include <windows.h>
193 #define sleep( sec ) do{Sleep( sec*1000 );}while(0)
194 #else
195 #include <unistd.h>
196 #include <stdio.h>
197 #include <pwd.h>
198 #endif
199 #endif
200 #include <string>
201 #include <vector>
202 #include <stdlib.h>
203 #include <string.h>
204 #include <stdio.h>
205 #include <stdarg.h>
206 
207 #include "inet_file.h"
208 int fadeout = 0, fadein = 0;
209 float volume = 0;
210 int bits = 0, done = 0;
211 
212 /*
213  *****************************************************************************
214  * some simple exit and error routines
215  */
216 void errorv( char *str, va_list ap )
217 {
218 #ifdef HAVE_SDL
219  vfprintf( stderr, str, ap );
220 
221  fprintf( stderr, ": %s.\n", SDL_GetError() );
222 #endif
223 }
224 int GetMaxVolume()
225 {
226 #ifdef __APPLE__
227  static int maxVol = FSOUND_GetSFXMasterVolume();
228  return maxVol;
229 
230 #else
231 #ifdef HAVE_SDL
232  return SDL_MIX_MAXVOLUME;
233 
234 #else
235  return 100
236 #endif
237 #endif
238 }
239 void cleanExit( char *str, ... )
240 {
241 #ifdef HAVE_SDL
242  va_list ap;
243 
244  va_start( ap, str );
245  errorv( str, ap );
246  va_end( ap );
247  Mix_CloseAudio();
248  SDL_Quit();
249 #endif
250  exit( 1 );
251 }
252 
253 /*
254  *****************************************************************************
255  * The main function
256  */
257 void changehome( bool to, bool linuxhome = true )
258 {
259  static std::vector< std::string >paths;
260  if (to) {
261  char mycurpath[8192];
262  getcwd( mycurpath, 8191 );
263  mycurpath[8191] = '\0';
264  paths.push_back( std::string( mycurpath ) );
265 #ifndef _WIN32
266  if (linuxhome) {
267  struct passwd *pwent;
268  pwent = getpwuid( getuid() );
269  chdir( pwent->pw_dir );
270  }
271 #endif
272  chdir( ".vegastrike" );
273  } else if ( !paths.empty() ) {
274  chdir( paths.back().c_str() );
275  paths.pop_back();
276  }
277 }
278 #ifdef _WIN32
279 #undef main
280 #endif
281 bool sende = true;
282 bool invalid_string = true;
283 std::string curmus;
284 
285 Music PlayMusic( const char *file, Music &oldmusic )
286 {
287  Music music;
288  music.Load( file );
289  if (music.m == NULL) {
290  changehome( true, false );
291  music.Load( file );
292  changehome( false );
293  if (music.m == NULL) {
294  changehome( true, true );
295  music.Load( file );
296  changehome( false );
297  if (music.m == NULL)
298  return oldmusic;
299  }
300  }
301  sende = false;
302  music.Play( fadeout, fadein, oldmusic );
303 
304  sende = true;
305  curmus = file;
306  invalid_string = false;
307  return music;
308 }
309 int mysocket_read = -1;
310 int mysocket_write = -1;
312 {
313  if (sende) {
314  char data = 'e';
315  e_already_sent = true;
316  fNET_Write( mysocket_write, sizeof (char), &data );
317  printf( "\ne\n[SONG DONE]\n" );
318  invalid_string = true;
319  }
320 }
322 {
323 #ifdef __MACH__
324 //Disable timesharing
325  {
326  kern_return_t error;
327  thread_extended_policy_data_t extendedPolicy;
328  thread_precedence_policy_data_t precedencePolicy;
329 
330  extendedPolicy.timeshare = 0;
331  error = thread_policy_set( mach_thread_self(),
332  THREAD_EXTENDED_POLICY,
333  (thread_policy_t) &extendedPolicy,
334  THREAD_EXTENDED_POLICY_COUNT );
335  if (error != KERN_SUCCESS) {
336 #if DEBUG
337  mach_error( "Couldn't set feeder thread's extended policy",
338  error );
339 #endif
340  }
341  precedencePolicy.importance = 1;
342  error = thread_policy_set( mach_thread_self(),
343  THREAD_PRECEDENCE_POLICY,
344  (thread_policy_t) &precedencePolicy,
345  THREAD_PRECEDENCE_POLICY_COUNT );
346  if (error != KERN_SUCCESS) {
347 #if DEBUG
348  mach_error( "Couldn't set feeder thread's precedence policy",
349  error );
350 #endif
351  }
352  }
353 #endif
354 }
355 int main( int argc, char **argv )
356 {
358  Music music;
359  int audio_rate, audio_channels,
360  //set this to any of 512,1024,2048,4096
361  //the higher it is, the more FPS shown and CPU needed
362  audio_buffers = 4096;
363 #ifdef HAVE_SDL
364  Uint16 audio_format;
365  //initialize SDL for audio and video
366  if (SDL_Init( SDL_INIT_AUDIO ) < 0)
367  cleanExit( "SDL_Init\n" );
368  Mix_HookMusicFinished( &music_finished );
369 #else
370 #ifdef __APPLE__
371  if ( !FSOUND_Init( 44100, 64, FSOUND_INIT_GLOBALFOCUS ) ) {
372  printf( "SOUND Error %d\n", FSOUND_GetError() );
373  exit( 1 );
374  }
375 #endif
376 #endif
377  fNET_startup();
378  GetMaxVolume();
379  //initialize sdl mixer, open up the audio device
380 #ifdef HAVE_SDL
381  if (Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, audio_buffers ) < 0)
382  cleanExit( "Mix_OpenAudio\n" );
383  //print out some info on the audio device and stream
384  Mix_QuerySpec( &audio_rate, &audio_format, &audio_channels );
385  bits = audio_format&0xFF;
386 #endif
387  printf( "Opened audio at %d Hz %d bit %s, %d bytes audio buffer\n", audio_rate,
388  bits, audio_channels > 1 ? "stereo" : "mono", audio_buffers );
389 
390  //load the song
391  printf( "argv %d\n\n\n", argc );
392  if (argc != 3) {
393  for (int i = 0; i < 10 && mysocket_write == -1; i++) {
394  mysocket_write = fNET_AcceptFrom( 4364, "localhost" );
395  mysocket_read = mysocket_write;
396  }
397  if (mysocket_write == -1)
398  return 1;
399  } else {
400  mysocket_write = open( argv[2], O_WRONLY|O_SHLOCK|O_CREAT, 0xffffffff );
401  mysocket_read = open( argv[1], O_RDONLY|O_SHLOCK|O_CREAT, 0xffffffff );
402  }
403  printf( "\n[CONNECTED]\n" );
404  char ministr[2] = {'\0', '\0'};
405  while (!done) {
406 //if ((Mix_PlayingMusic() || Mix_PausedMusic())&&(!done)) {
407  char arg;
408  std::string str;
409  arg = fNET_fgetc( mysocket_read );
410  printf( "%c", arg );
411  switch (arg)
412  {
413  case 'p':
414  case 'P':
415  arg = fNET_fgetc( mysocket_read );
416  while (arg != '\0' && arg != '\n') {
417  if (arg != '\r') {
418  ministr[0] = arg;
419  str += ministr;
420  }
421  arg = fNET_fgetc( mysocket_read );
422  }
423  printf( "%s", str.c_str() );
424  if ( (str != curmus || invalid_string)
425 #ifdef HAVE_SDL
426  || ( !Mix_PlayingMusic() )
427 #endif
428  ) {
429  music = PlayMusic( str.c_str(), music );
430  if (music.m) {
431  printf( "\n[PLAYING %s WITH %d FADEIN AND %d FADEOUT]\n", str.c_str(), fadein, fadeout );
432  curmus = str;
433  invalid_string = false;
434  } else {
435  printf( "\n[UNABLE TO PLAY %s WITH %d FADEIN AND %d FADEOUT]\n", str.c_str(), fadein, fadeout );
436  music_finished();
437  }
438  } else {
439  printf( "\n[%s WITH %d FADEIN AND %d FADEOUT IS ALREADY PLAYING]\n", str.c_str(), fadein, fadeout );
440  }
441  break;
442  case 'i':
443  case 'I':
444  arg = fNET_fgetc( mysocket_read );
445  while (arg != '\0' && arg != '\n') {
446  if (arg != '\r') {
447  ministr[0] = arg;
448  str += ministr;
449  }
450  arg = fNET_fgetc( mysocket_read );
451  }
452  printf( "%s", str.c_str() );
453  fadein = atoi( str.c_str() );
454  printf( "\n[SETTING FADEIN TO %d]\n", fadein );
455  break;
456  case 'o':
457  case 'O':
458  arg = fNET_fgetc( mysocket_read );
459  while (arg != '\0' && arg != '\n') {
460  if (arg != '\r') {
461  ministr[0] = arg;
462  str += ministr;
463  }
464  arg = fNET_fgetc( mysocket_read );
465  }
466  printf( "%s", str.c_str() );
467  fadeout = atoi( str.c_str() );
468  printf( "\n[SETTING FADEOUT TO %d]\n", fadeout );
469  break;
470  case 'v':
471  case 'V':
472  arg = fNET_fgetc( mysocket_read );
473  while (arg != '\0' && arg != '\n') {
474  if (arg != '\r') {
475  ministr[0] = arg;
476  str += ministr;
477  }
478  arg = fNET_fgetc( mysocket_read );
479  }
480  printf( "%s", str.c_str() );
481  volume = atof( str.c_str() );
482  printf( "\n[SETTING VOLUME TO %f]\n", volume );
483  music.SetMasterVolume( volume );
484  break;
485  case 't':
486  case 'T':
487  case '\0':
488  fNET_close( mysocket_read );
489  if (mysocket_read != mysocket_write)
490  fNET_close( mysocket_write );
491  done = true;
492  printf( "\n[TERMINATING MUSIC SERVER]\n" );
493  break;
494  }
495  }
496  //free & close
497  fNET_cleanup();
498 #ifdef HAVE_SDL
499  Mix_CloseAudio();
500  SDL_Quit();
501 #endif
502 
503  return 0;
504 }
505