void writeSound(void) { int ret = soundBufferLen; static int countdown = 20; decode_pos_ms += (ret/(2*sndNumChannels) * 1000) / (float)sndSamplesPerSec; _playback->output->write_audio (soundFinalWave, soundBufferLen); if (--countdown == 0) { countdown = 20; } /* is seek request complete? (-2) */ if (seek_needed == -2) { _playback->output->flush(decode_pos_ms); // Scroll to new position in track seek_needed = -1; } if (lastfn != NULL && (seek_needed != -1)) //if a seek is initiated { if (seek_needed < decode_pos_ms) //if we are asked to seek backwards. we have to start from the beginning { GSFClose(); GSFRun(lastfn); decode_pos_ms = 0; } } }
void writeSound(void) { int ret = soundBufferLen; //int i; while (mod.outMod->CanWrite() < ((ret*sndNumChannels*(sndBitsPerSample/8))<<(mod.dsp_isactive()?1:0))) Sleep(50); mod.SAAddPCMData((char *)soundFinalWave,sndNumChannels,sndBitsPerSample,decode_pos_ms); mod.VSAAddPCMData((char *)soundFinalWave,sndNumChannels,sndBitsPerSample,decode_pos_ms); decode_pos_ms += (ret/(2*sndNumChannels) * 1000) / (float)sndSamplesPerSec; if (mod.dsp_isactive()) ret=mod.dsp_dosamples((short *)soundFinalWave,ret/sndNumChannels/(sndBitsPerSample/8),sndBitsPerSample,sndNumChannels,sndSamplesPerSec)*(sndNumChannels*(sndBitsPerSample/8)); //if(soundFinalWave[0]==0&&soundFinalWave[1]==0&&soundFinalWave[2]==0&&soundFinalWave[3]==0) // DisplayError("%.2X%.2X%.2X%.2X - %d", soundFinalWave[0],soundFinalWave[1],soundFinalWave[2],soundFinalWave[3],ret); mod.outMod->Write((char *)&soundFinalWave,ret); if (seek_needed != -1) //if a seek is initiated { mod.outMod->Flush((long)decode_pos_ms); if (seek_needed < decode_pos_ms) //if we are asked to seek backwards. we have to start from the beginning { GSFClose(); GSFRun(lastfn); decode_pos_ms = 0; } } }
int play(char *fn) { int maxlatency; int thread_id; input_file = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (input_file == INVALID_HANDLE_VALUE) // error opening file { return 1; } file_length=GetFileSize(input_file,NULL); if(IsCurrentFile) { if(!strcmp(fn,lastfn)) { IsCurrentFile = TRUE; SongChanged=FALSE; } else { IsCurrentFile = FALSE; SongChanged=TRUE; } } strcpy(lastfn,fn); paused=0; decode_pos_ms=0; seek_needed=-1; GSFRun(fn); maxlatency = mod.outMod->Open(sndSamplesPerSec,sndNumChannels,sndBitsPerSample, -1,-1); if (maxlatency < 0) // error opening device { CloseHandle(input_file); input_file=INVALID_HANDLE_VALUE; return 1; } // dividing by 1000 for the first parameter of setinfo makes it // display 'H'... for hundred.. i.e. 14H Kbps. mod.SetInfo((sndSamplesPerSec*sndBitsPerSample*sndNumChannels)/1000,sndSamplesPerSec/1000,sndNumChannels,1); // initialize vis stuff mod.SAVSAInit(maxlatency,sndSamplesPerSec); mod.VSASetInfo(sndSamplesPerSec,sndNumChannels); mod.outMod->SetVolume(-666); // set the output plug-ins default volume killDecodeThread=0; thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) DecodeThread,(void *) &killDecodeThread,0,&thread_id); return 0; }
gboolean gsf_play_loop(const gchar * filename) { int r; const gchar *fn; fn = g_filename_from_uri(filename, NULL, NULL); r = GSFRun(fn); if (!r) return -1; lastfn = g_strdup(fn); _playback->output->open_audio(FMT_S16_LE, sndSamplesPerSec, sndNumChannels); //gint length = tuple_get_int(ti, FIELD_LENGTH, NULL); _playback->set_params(_playback, sndSamplesPerSec*2*2*8, sndSamplesPerSec, sndNumChannels); decode_pos_ms = 0; seek_needed = -1; TrailingSilence=1000; stop_flag = FALSE; _playback->set_pb_ready(_playback); while(! stop_flag) EmulationLoop(); GSFClose(); stop_flag = TRUE; _playback->output->abort_write(); #if _AUD_PLUGIN_VERSION_MIN < 40 _playback->output->close_audio(); //Fixes issue when switching tracks manually. #endif g_free(lastfn); lastfn = NULL; return 0; }
JNIEXPORT jlong JNICALL Java_com_ssb_droidsound_plugins_GSFPlugin_N_1loadFile(JNIEnv *env, jobject obj, jstring fname) { decode_pos_ms = 0; //seek_needed = -1; TrailingSilence=1000; IgnoreTrackLength=1; DetectSilence=1; silencedetected=0; playforever=0; const char *file_name = env->GetStringUTFChars(fname, NULL); if(fifo == NULL) fifo = new Fifo(128 * 1024); int r = GSFRun((char*)file_name); __android_log_print(ANDROID_LOG_VERBOSE, "GSF", "LOAD: %d, bufSize: %d", r, soundBufferLen); return 1; }
int main(int argc, char **argv) { int r, tmp, fi, random=0; char Buffer[1024]; char length_str[256], fade_str[256], volume[256], title_str[256]; char tmp_str[256]; char *tag; soundLowPass = 0; soundEcho = 0; soundQuality = 0; DetectSilence=1; silencelength=5; IgnoreTrackLength=0; DefaultLength=150000; TrailingSilence=1000; playforever=0; while((r=getopt(argc, argv, "hlsrieWL:t:"))>=0) { char *e; switch(r) { case 'h': printf("playgsf version %s (based on Highly Advanced version %s)\n\n", VERSION_STR, HA_VERSION_STR); printf("Usage: ./playgsf [options] files...\n\n"); printf(" -l Enable low pass filer\n"); printf(" -s Detect silence\n"); printf(" -L Set silence length in seconds (for detection). Default 5\n"); printf(" -t Set default track length in milliseconds. Default 150000 ms\n"); printf(" -i Ignore track length (use default length)\n"); printf(" -e Endless play\n"); printf(" -r Play files in random order\n"); printf(" -W output to 'output.wav' rather than soundcard\n"); printf(" -h Displays what you are reading right now\n"); return 0; break; case 'i': IgnoreTrackLength = 1; break; case 'l': soundLowPass = 1; break; case 's': DetectSilence = 1; break; case 'L': silencelength = strtol(optarg, &e, 0); if (e==optarg) { fprintf(stderr, "Bad value\n"); return 1; } break; case 'e': playforever = 1; break; case 't': DefaultLength = strtol(optarg, &e, 0); if (e==optarg) { fprintf(stderr, "Bad value\n"); return 1; } break; case 'r': random = 1; break; case 'W': fileoutput = 1; break; case '?': fprintf(stderr, "Unknown argument. try -h\n"); return 1; break; } } if (argc-optind<=0) { printf("No files specified! For help, try -h\n"); return 1; } if (random) { shuffle_list(&argv[optind], argc-optind); } printf("playgsf version %s (based on Highly Advanced version %s)\n\n", VERSION_STR, HA_VERSION_STR); signal(SIGINT, signal_handler); tag = (char*)malloc(50001); fi = optind; while (!g_must_exit && fi < argc) { decode_pos_ms = 0; seek_needed = -1; TrailingSilence=1000; r = GSFRun(argv[fi]); if (!r) { fi++; continue; } g_playing = 1; psftag_readfromfile((void*)tag, argv[fi]); BOLD(); printf("Filename: "); NORMAL(); printf("%s\n", basename(argv[fi])); BOLD(); printf("Channels: "); NORMAL(); printf("%d\n", sndNumChannels); BOLD(); printf("Sample rate: "); NORMAL(); printf("%d\n", sndSamplesPerSec); if (!psftag_getvar(tag, "title", title_str, sizeof(title_str)-1)) { BOLD(); printf("Title: "); NORMAL(); printf("%s\n", title_str); } if (!psftag_getvar(tag, "artist", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Artist: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "game", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Game: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "year", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Year: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "copyright", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Copyright: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "gsfby", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("GSF By: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "tagger", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Tagger: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "comment", tmp_str, sizeof(tmp_str)-1)) { BOLD(); printf("Comment: "); NORMAL(); printf("%s\n", tmp_str); } if (!psftag_getvar(tag, "fade", fade_str, sizeof(fade_str)-1)) { FadeLength = LengthFromString(fade_str); BOLD(); printf("Fade: "); NORMAL(); printf("%s (%d ms)\n", fade_str, FadeLength); } if (!psftag_raw_getvar(tag, "length", length_str, sizeof(length_str)-1)) { TrackLength = LengthFromString(length_str) + FadeLength; BOLD(); printf("Length: "); NORMAL(); printf("%s (%d ms) ", length_str, TrackLength); if (IgnoreTrackLength) { printf("(ignored)"); TrackLength = DefaultLength; } printf("\n"); } else { TrackLength = DefaultLength; } /* Must be done after GSFrun so sndNumchannels and * sndSamplesPerSec are set to valid values */ ao_initialize(); ao_sample_format format_ao = { 16, sndSamplesPerSec, sndNumChannels, AO_FMT_LITTLE }; if(fileoutput) { snd_ao = ao_open_file(ao_driver_id("wav"), "output.wav", 1, &format_ao, NULL); } else { snd_ao = ao_open_live(ao_default_driver_id(), &format_ao, NULL); } while(g_playing) { int remaining = TrackLength - (int)decode_pos_ms; if (remaining<0) { // this happens during silence period remaining = 0; } EmulationLoop(); BOLD(); printf("Time: "); NORMAL(); printf("%02d:%02d.%02d ", (int)(decode_pos_ms/1000.0)/60, (int)(decode_pos_ms/1000.0)%60, (int)(decode_pos_ms/10.0)%100); if (!playforever) { /*BOLD();*/ printf("["); /*NORMAL();*/ printf("%02d:%02d.%02d", remaining/1000/60, (remaining/1000)%60, (remaining/10%100) ); /*BOLD();*/ printf("] of "); /*NORMAL();*/ printf("%02d:%02d.%02d ", TrackLength/1000/60, (TrackLength/1000)%60, (TrackLength/10%100)); } BOLD(); printf(" GBA Cpu: "); NORMAL(); printf("%02d%% ", cpupercent); printf(" \r"); fflush(stdout); } printf("\n--\n"); ao_close(snd_ao); fi++; } ao_shutdown(); return 0; }