static void SetInfo(void) { nsf_t * nsf = app.nsf; unsigned int ms; gchar *name = 0; unsigned int track = app.cur_track; pdebug("nsf : set info #%02u\n", track); ms = 0; if (!track || track > app.n_tracks) { ms = app.tracks[0].ms; } else { unsigned int tms = app.tracks[track].ms; ms = app.tracks[0].ms; name = g_strdup_printf("%s by %s track:%02d %02u:%02u copyright:%s :-)", nsf->song_name, nsf->artist_name, track, tms/60000u, tms%60000u/1000u, nsf->copyright); nosefart_ip.set_info_text(name); g_free(name); } name = make_name(nsf->song_name, nsf->artist_name, track, app.n_tracks); nosefart_ip.set_info(name, ms, 44100, 44100, 1); g_free(name); /* $$$ ? */ }
OPStatus InputPlugin::loadPlugin(const char * libPath, InputPlugin*& outplug) { if (nullptr != outplug) { LOG_DEBUG(InputPlugin) << "Existing Plugin object"; return OP_ERROR; } InputPlugin* plugin = new InputPlugin; if (OP_ERROR == loadLibrary(libPath, plugin->_libHandle, plugin->_pluginInfo)) { delete plugin; LOG_ERROR(InputPlugin) << "Error loading library " << libPath; return OP_ERROR; } //Find entries for functions in DLL void(*InitFunc)(void); plugin->loadDefaults(); plugin->loadPJ64Settings(); getPluginFunction(plugin->_libHandle, "ControllerCommand", plugin->ControllerCommand); getPluginFunction(plugin->_libHandle, "InitiateControllers", InitFunc); getPluginFunction(plugin->_libHandle, "ReadController", plugin->ReadController); getPluginFunction(plugin->_libHandle, "GetKeys", plugin->GetKeys); getPluginFunction(plugin->_libHandle, "RumbleCommand", plugin->RumbleCommand); //version 102 functions getPluginFunction(plugin->_libHandle, "PluginLoaded", plugin->PluginOpened); //Make sure dll had all needed functions if (InitFunc == nullptr || plugin->CloseLib == nullptr) { freeLibrary(plugin->_libHandle); delete plugin; LOG_ERROR(InputPlugin) << "Invalid plugin: not all required functions are found"; return OP_ERROR; } if (plugin->_pluginInfo.Version >= 0x0102) { if (plugin->PluginOpened == nullptr) { freeLibrary(plugin->_libHandle); delete plugin; LOG_ERROR(InputPlugin) << "Invalid plugin: not all required functions are found"; return OP_ERROR; } plugin->PluginOpened(); } // Return it outplug = plugin; plugin = nullptr; return OP_OK; }
void FormPlaylist::pluginOptions() { InputPlugin *iplug = NULL; if ( Func.chkFNr( Func.nr() ) ) iplug = Func.getMusicFormat( playList[1][Func.nr()], playList[2][Func.nr()] ); if ( iplug && iplug->showOptions ) iplug->showOptions(); }
static void *asap_play_thread(void *arg) { while (thread_run) { static unsigned char buffer[BUFFERED_BLOCKS * (BITS_PER_SAMPLE / 8) * 2]; int buffered_bytes; if (generated_eof) { xmms_usleep(10000); continue; } if (seek_to >= 0) { mod.output->flush(seek_to); ASAP_Seek(asap, seek_to); seek_to = -1; } buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8); buffered_bytes = ASAP_Generate(asap, buffer, buffered_bytes, BITS_PER_SAMPLE == 8 ? ASAPSampleFormat_U8 : ASAPSampleFormat_S16_L_E); if (buffered_bytes == 0) { generated_eof = TRUE; mod.output->buffer_free(); mod.output->buffer_free(); continue; } mod.add_vis_pcm(mod.output->written_time(), BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_LE, channels, buffered_bytes, buffer); while (thread_run && mod.output->buffer_free() < buffered_bytes) xmms_usleep(20000); if (thread_run) mod.output->write_audio(buffer, buffered_bytes); } pthread_exit(NULL); }
static void asap_play_file(char *filename) { const ASAPInfo *info; int song; int duration; char *title; if (asap == NULL) return; if (!asap_load_file(filename)) return; if (!ASAP_Load(asap, filename, module, module_len)) return; info = ASAP_GetInfo(asap); song = ASAPInfo_GetDefaultSong(info); duration = ASAPInfo_GetDuration(info, song); if (!ASAP_PlaySong(asap, song, duration)) return; channels = ASAPInfo_GetChannels(info); if (!mod.output->open_audio(BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_LE, ASAP_SAMPLE_RATE, channels)) return; title = asap_get_title(filename, info); mod.set_info(title, duration, BITS_PER_SAMPLE * 1000, ASAP_SAMPLE_RATE, channels); g_free(title); seek_to = -1; thread_run = TRUE; generated_eof = FALSE; pthread_create(&thread_handle, NULL, asap_play_thread, NULL); }
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class InputPluginList getInputPlugins() { InputPlugin* PLUGIN_POOL[] = { new KeyboardMouseDevice(), new TouchscreenDevice(), nullptr }; InputPluginList result; for (int i = 0; PLUGIN_POOL[i]; ++i) { InputPlugin* plugin = PLUGIN_POOL[i]; if (plugin->isSupported()) { result.push_back(InputPluginPointer(plugin)); } } return result; }
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class InputPluginList getInputPlugins() { InputPlugin* PLUGIN_POOL[] = { new KeyboardMouseDevice(), new SDL2Manager(), new SixenseManager(), new ViveControllerManager(), nullptr }; InputPluginList result; for (int i = 0; PLUGIN_POOL[i]; ++i) { InputPlugin* plugin = PLUGIN_POOL[i]; if (plugin->isSupported()) { plugin->init(); result.push_back(InputPluginPointer(plugin)); } } return result; }
void sid_subtune (int tune) { bool was_running = false; int ret; #ifdef DEBUG printf ("sid_subtune\n"); #endif if(running) { // Basically copied from above. was_running = true; running = false; pthread_join (play_thread, NULL); } pthread_mutex_lock (&lib_mutex); { // Get tune number we ended up on sid2_playerInfo_t playerInfo; sidplayer.lib.getInfo (&playerInfo); if (tune > 0) sidplayer.selectedSong++; else sidplayer.selectedSong = 1; if (sidplayer.selectedSong > playerInfo.tuneInfo.songs) sidplayer.selectedSong = 1; } sidplayer.song.selectSong (sidplayer.selectedSong); sidplayer.lib.loadSong (&sidplayer.song); { // Get tune number we ended up on sid2_playerInfo_t playerInfo; sidplayer.lib.getInfo (&playerInfo); sidplayer.selectedSong = playerInfo.tuneInfo.currentSong; } pthread_mutex_unlock (&lib_mutex); sid_ip.output->flush (0); { // Redefine song name char *title; sid2_playerInfo_t playerInfo; sidplayer.lib.getInfo (&playerInfo); sid_create_title (playerInfo.tuneInfo, &title); if (title) sid_ip.set_info_text (title); } if (was_running) { running = true; pthread_create (&play_thread, NULL, playloop, NULL); } }
static void driver_callback(void *b, int i) { xmp_ip.add_vis_pcm(xmp_ip.output->written_time(), xmp_cfg.force8bit ? FMT_U8 : FMT_S16_NE, xmp_cfg.force_mono ? 1 : 2, i, b); while (xmp_ip.output->buffer_free() < i && playing) usleep(10000); if (playing) xmp_ip.output->write_audio(b, i); }
// if plugin isn't initialized, init and load config void Initialize(void* const hwnd) { // add 4 gcpads for (unsigned int i=0; i<4; ++i) g_plugin.controllers.push_back(new GCPad(i)); g_controller_interface.SetHwnd(hwnd); g_controller_interface.Initialize(); // load the saved controller config g_plugin.LoadConfig(true); }
static void play_file(char *filename) { char *tmp; struct driveinfo *drive; int track; int track_len; if ((drive = cdda_find_drive(filename)) == NULL) return; if (is_mounted(drive->device)) return; tmp = strrchr(filename, '/'); if (tmp) tmp++; else tmp = filename; if (!sscanf(tmp, "Track %d.cda", &track)) return; if (track < 0 || track > 99) return; if (!cdda_get_toc(&cdda_playing.cd_toc, drive->device) || cdda_playing.cd_toc.track[track].flags.data_track || track < cdda_playing.cd_toc.first_track || track > cdda_playing.cd_toc.last_track) return; if ((cdda_playing.fd = open(drive->device, CDOPENFLAGS)) == -1) return; track_len = cdda_calculate_track_length(&cdda_playing.cd_toc, track); cdda_ip.set_info(cdda_get_title(&cdda_playing.cd_toc, track), (track_len * 1000) / 75, 44100 * 2 * 2 * 8, 44100, 2); memcpy(&cdda_playing.drive, drive, sizeof (struct driveinfo)); #ifndef CDDA_HAS_READAUDIO cdda_playing.drive.dae = FALSE; #endif cdda_playing.track = track; is_paused = FALSE; timeout_remove_for_device(drive->device); cdda_playing.playing = TRUE; if (drive->dae) dae_play(); else seek(0); }
void process_buffer(size_t num_samples) { int tsamples = num_samples * num_channels; if (!(WavpackGetMode (ctx) & MODE_FLOAT)) { float scaler = (float) (1.0 / ((unsigned int32_t) 1 << (bytes_per_sample * 8 - 1))); float *fptr = (float *) input; int32_t *lptr = input; int cnt = tsamples; while (cnt--) *fptr++ = *lptr++ * scaler; } if (play_gain != 1.0) { float *fptr = (float *) input; int cnt = tsamples; while (cnt--) *fptr++ *= play_gain; } if (tsamples) { float *fptr = (float *) input; short *sptr = (short *) output; int cnt = num_samples, ch; while (cnt--) for (ch = 0; ch < num_channels; ++ch) { int dst; *fptr -= shaping_error [ch]; if (*fptr >= 1.0) dst = 32767; else if (*fptr <= -1.0) dst = -32768; else dst = (int) floor (*fptr * 32768.0); shaping_error [ch] = (float)(dst / 32768.0 - *fptr++); *sptr++ = dst; } } if (EQ_on) iir ((char *) output, tsamples * sizeof(int16_t)); mod->add_vis_pcm(mod->output->written_time(), FMT_S16_NE, num_channels, tsamples * sizeof(int16_t), output); mod->output->write_audio(output, tsamples * sizeof(int16_t)); }
// Assume file to have been loaded by void sid_play (char *filename) { int ret; #ifdef DEBUG printf ("sid_play\n"); #endif sid_ip.filename = filename; sidplayer.selectedSong = 0; pthread_mutex_lock (&lib_mutex); sidplayer.song.load (filename); if (sidplayer.song) { // Get tune number we ended up on sid2_playerInfo_t playerInfo; sidplayer.song.selectSong (sidplayer.selectedSong); sidplayer.lib.loadSong (&sidplayer.song); sidplayer.lib.getInfo (&playerInfo); sidplayer.selectedSong = playerInfo.tuneInfo.currentSong; } pthread_mutex_unlock (&lib_mutex); if (ret < 0) return; // Allocate buffer (250 msec) sidplayer.bufferSize = 512 * (SID2_DEFAULT_PRECISION / 8) * 2; sidplayer.buffer = (uint_least8_t *) malloc (sizeof (uint_least8_t) * sidplayer.bufferSize); if (!sidplayer.buffer) return; // OPEN AUDIO. if (sid_ip.output->open_audio(FMT_S16_LE, SID2_DEFAULT_SAMPLING_FREQ, 2) /* Stereo */ == 0) { return; } { // Bits per second int rate = SID2_DEFAULT_SAMPLING_FREQ * SID2_DEFAULT_PRECISION * 2; int length; char *title; sid_song_info (filename, &title, &length); sid_ip.set_info (title, length, rate, SID2_DEFAULT_SAMPLING_FREQ, 2); } running = true; pthread_create (&play_thread, NULL, playloop, NULL); }
static void *playloop (void *arg) { uint_least8_t *buffer = sidplayer.buffer; int length = sidplayer.bufferSize; while (running) { pthread_mutex_lock (&lib_mutex); (void) sidplayer.lib.play (buffer, length); pthread_mutex_unlock (&lib_mutex); sid_ip.add_vis_pcm (sid_ip.output->written_time(), FMT_S16_LE, 2, length, buffer); while ((sid_ip.output->buffer_free() < length) && running) xmms_usleep(10000); sid_ip.output->write_audio (buffer, length); } }
static void driver_callback(void *b, int i) { #if __AUDACIOUS_PLUGIN_API__ >= 2 play_data.ipb->pass_audio(play_data.ipb, play_data.fmt, play_data.nch, i, b, &play_data.ipb->playing); #else xmp_ip.add_vis_pcm(xmp_ip.output->written_time(), xmp_cfg.force8bit ? FMT_U8 : FMT_S16_NE, xmp_cfg.force_mono ? 1 : 2, i, b); while (xmp_ip.output->buffer_free() < i && play_data.ipb->playing) usleep(10000); if (play_data.ipb->playing) xmp_ip.output->write_audio(b, i); #endif }
static void uade_info_string(void) { char info[256]; int playtime = state.song->playtime; /* Hack. Set info text and song length late because we didn't know subsong amounts before this. Pass zero as a length so that the graphical play time counter will run but seek is still enabled. Passing -1 as playtime would disable seeking. */ if (playtime <= 0) playtime = 0; if (uade_generate_song_title(info, sizeof info, &state)) strlcpy(info, gui_filename, sizeof info); uade_ip.set_info(info, playtime, UADE_BYTES_PER_FRAME * state.config.frequency, state.config.frequency, UADE_CHANNELS); }
// if plugin isn't initialized, init and load config void Initialize(void* const hwnd, bool wait) { // add 4 wiimotes for (unsigned int i = WIIMOTE_CHAN_0; i<MAX_BBMOTES; ++i) g_plugin.controllers.push_back(new WiimoteEmu::Wiimote(i)); g_controller_interface.SetHwnd(hwnd); g_controller_interface.Initialize(); g_plugin.LoadConfig(false); WiimoteReal::Initialize(wait); // reload Wiimotes with our settings if (Movie::IsPlayingInput() || Movie::IsRecordingInput()) Movie::ChangeWiiPads(); }
bool attach(const char *filename) { ctx = WavpackOpenFileInput(filename, error_buff, OPEN_TAGS | OPEN_WVC | OPEN_NORMALIZE, 0); if (ctx == NULL) { return false; } sample_rate = WavpackGetSampleRate(ctx); num_channels = WavpackGetNumChannels(ctx); bytes_per_sample = WavpackGetBytesPerSample(ctx); input = (int32_t *)calloc(BUFFER_SIZE, num_channels * sizeof(int32_t)); output = (int16_t *)calloc(BUFFER_SIZE, num_channels * sizeof(int16_t)); memset (shaping_error, 0, sizeof (shaping_error)); mod->set_info(generate_title(filename, ctx), (int) (WavpackGetNumSamples(ctx) / sample_rate) * 1000, (int) WavpackGetAverageBitrate(ctx, true), (int) sample_rate, num_channels); play_gain = calculate_gain (ctx); DBG("gain value = %g\n", play_gain); return true; }
static void play_file(char *filename) { FILE *fp; static unsigned char module[65000]; unsigned int module_len; fp = fopen(filename, "rb"); if (fp == NULL) return; module_len = fread(module, 1, sizeof(module), fp); fclose(fp); if (!ASAP_Load(filename, module, module_len)) return; ASAP_PlaySong(ASAP_GetDefSong()); channels = ASAP_GetChannels(); buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8); if (!mod.output->open_audio(BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_NE, FREQUENCY, channels)) return; mod.set_info(NULL, -1, BITS_PER_SAMPLE * 1000, FREQUENCY, channels); thread_run = TRUE; pthread_create(&thread_handle, NULL, play_thread, NULL); }
static void *play_thread(void *arg) { for (;;) { static #if BITS_PER_SAMPLE == 8 unsigned char #else short int #endif buffer[BUFFERED_BLOCKS * 2]; ASAP_Generate(buffer, buffered_bytes); mod.add_vis_pcm(mod.output->written_time(), BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_NE, channels, buffered_bytes, buffer); while (thread_run && mod.output->buffer_free() < buffered_bytes) xmms_usleep(20000); if (!thread_run) break; mod.output->write_audio(buffer, buffered_bytes); } mod.output->buffer_free(); mod.output->buffer_free(); pthread_exit(NULL); }
static void asap_play_file(char *filename) { int song; int duration; char *title; if (!asap_load_file(filename)) return; if (!ASAP_Load(&asap, filename, module, module_len)) return; song = asap.module_info.default_song; duration = asap.module_info.durations[song]; ASAP_PlaySong(&asap, song, duration); channels = asap.module_info.channels; if (!mod.output->open_audio(BITS_PER_SAMPLE == 8 ? FMT_U8 : FMT_S16_LE, ASAP_SAMPLE_RATE, channels)) return; title = asap_get_title(filename, &asap.module_info); mod.set_info(title, duration, BITS_PER_SAMPLE * 1000, ASAP_SAMPLE_RATE, channels); g_free(title); seek_to = -1; thread_run = TRUE; generated_eof = FALSE; pthread_create(&thread_handle, NULL, asap_play_thread, NULL); }
FXuint MP4Reader::mp4_seek(void*ptr,FXulong p){ InputPlugin* input = reinterpret_cast<InputPlugin*>(ptr); return input->position(p,FXIO::Begin); //return input->position(); }
FXuint MP4Reader::mp4_read(void*ptr,void*data,FXuint len){ InputPlugin* input = reinterpret_cast<InputPlugin*>(ptr); return (FXuint) input->read(data,len); }
static int demux_xmms_open(demuxer_t* demuxer) { InputPlugin* ip = NULL; sh_audio_t* sh_audio; WAVEFORMATEX* w; xmms_priv_t *priv; int i; if (xmms_priv) return 0; // as I said, it's not reentrant :) init_plugins(); for(i=0;i<no_plugins;i++){ if (input_plugins[i]->is_our_file(demuxer->stream->url)){ ip=input_plugins[i]; break; } } if(!ip) return 0; // no plugin to handle this... pthread_mutex_init(&xmms_mutex,NULL); xmms_priv=priv=malloc(sizeof(xmms_priv_t)); memset(priv,0,sizeof(xmms_priv_t)); priv->ip=ip; memset(xmms_audiobuffer,0,XMMS_PACKETSIZE); xmms_channels=0; sh_audio = new_sh_audio(demuxer,0); sh_audio->wf = w = malloc(sizeof(WAVEFORMATEX)); w->wFormatTag = sh_audio->format = format; demuxer->movi_start = 0; demuxer->movi_end = 100; demuxer->audio->id = 0; demuxer->audio->sh = sh_audio; demuxer->priv=priv; sh_audio->ds = demuxer->audio; xmms_output_plugin.init(); ip->output = &xmms_output_plugin; xmms_playing=1; ip->play_file(demuxer->stream->url); if (ip->get_song_info) ip->get_song_info(demuxer->stream->url,&xmms_title,&xmms_length); if (xmms_length<=0) demuxer->seekable=0; mp_msg(MSGT_DEMUX,MSGL_INFO,MSGTR_MPDEMUX_XMMS_WaitForStart, demuxer->stream->url); while (xmms_channels==0) { usleep(10000); if(ip->get_time()<0) return 0; } sh_audio->sample_format= xmms_afmt; switch (xmms_afmt) { case AF_FORMAT_S16_LE: case AF_FORMAT_S16_BE: case AF_FORMAT_U16_LE: case AF_FORMAT_U16_BE: sh_audio->samplesize = 2; break; default: sh_audio->samplesize = 1; } w->wBitsPerSample = sh_audio->samplesize*8; w->nChannels = sh_audio->channels = xmms_channels; w->nSamplesPerSec = sh_audio->samplerate = xmms_samplerate; xmms_byterate = w->nAvgBytesPerSec = xmms_samplerate*sh_audio->channels*sh_audio->samplesize; w->nBlockAlign = sh_audio->samplesize*sh_audio->channels; w->cbSize = 0; return DEMUXER_TYPE_XMMS; }
void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) { int ret; InputStream inStream; InputPlugin * plugin = NULL; char * path; if(isRemoteUrl(pc->utf8url)) { path = utf8StrToLatin1Dup(pc->utf8url); } else path = strdup(rmp2amp(utf8ToFsCharset(pc->utf8url))); if(!path) { dc->error = DECODE_ERROR_FILE; dc->state = DECODE_STATE_STOP; dc->start = 0; return; } copyMpdTagToOutputBuffer(cb, NULL); strncpy(dc->utf8url, pc->utf8url, MAXPATHLEN); dc->utf8url[MAXPATHLEN] = '\0'; if(openInputStream(&inStream, path) < 0) { dc->error = DECODE_ERROR_FILE; dc->state = DECODE_STATE_STOP; dc->start = 0; free(path); return; } dc->seekable = inStream.seekable; dc->state = DECODE_STATE_START; dc->start = 0; while(!inputStreamAtEOF(&inStream) && bufferInputStream(&inStream) < 0 && !dc->stop) { /* sleep so we don't consume 100% of the cpu */ // fprintf(stderr,"In decode.c decodeParent decode start func\r\n"); // my_usleep(1000); } if(dc->stop) { dc->state = DECODE_STATE_STOP; dc->stop = 0; free(path); return; } /*if(inStream.metaName) { MpdTag * tag = newMpdTag(); tag->name = strdup(inStream.metaName); copyMpdTagToOutputBuffer(cb, tag); freeMpdTag(tag); }*/ /* reset Metadata in OutputBuffer */ ret = DECODE_ERROR_UNKTYPE; if(isRemoteUrl(dc->utf8url)) { cb->acceptMetadata = 1; plugin = getInputPluginFromMimeType(inStream.mime); if(plugin == NULL) { plugin = getInputPluginFromSuffix( getSuffix(dc->utf8url)); } /* this is needed for bastard streams that don't have a suffix or set the mimeType */ if(plugin == NULL) { plugin = getInputPluginFromName("mp3"); } if(plugin && (plugin->streamTypes & INPUT_PLUGIN_STREAM_URL) && plugin->streamDecodeFunc) { ret = plugin->streamDecodeFunc(cb, dc, &inStream); } } else { cb->acceptMetadata = 0; plugin = getInputPluginFromSuffix(getSuffix(dc->utf8url)); if(plugin && (plugin->streamTypes && INPUT_PLUGIN_STREAM_FILE)) { if(plugin->streamDecodeFunc) { ret = plugin->streamDecodeFunc(cb, dc, &inStream); } else if(plugin->fileDecodeFunc) { closeInputStream(&inStream); ret = plugin->fileDecodeFunc(cb, dc, path); } } } if(ret<0 || ret == DECODE_ERROR_UNKTYPE) { strncpy(pc->erroredUrl, dc->utf8url, MAXPATHLEN); pc->erroredUrl[MAXPATHLEN] = '\0'; if(ret != DECODE_ERROR_UNKTYPE) dc->error = DECODE_ERROR_FILE; else { dc->error = DECODE_ERROR_UNKTYPE; closeInputStream(&inStream); } dc->stop = 0; dc->state = DECODE_STATE_STOP; } free(path); }
static void *mp4Decode(void *args) { FILE* mp4file; pthread_mutex_lock(&mutex); seekPosition = -1; bPlaying = TRUE; if(!(mp4file = fopen(args, "rb"))){ g_print("MP4!AAC - Can't open file\n"); g_free(args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } mp4_get_file_type(mp4file); fseek(mp4file, 0, SEEK_SET); if(mp4cfg.file_type == FILE_MP4){// We are reading a MP4 file mp4ff_callback_t* mp4cb; mp4ff_t* infile; gint mp4track; mp4cb = getMP4FF_cb(mp4file); if(!(infile = mp4ff_open_read(mp4cb))){ g_print("MP4 - Can't open file\n"); goto end; } if((mp4track = getAACTrack(infile)) < 0){ /* * TODO: check here for others Audio format..... * */ g_print("Unsupported Audio track type\n"); g_free(args); fclose(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ NeAACDecHandle decoder; unsigned char *buffer = NULL; guint bufferSize = 0; gulong samplerate; guchar channels; //guint avgBitrate; //MP4Duration duration; int msDuration; int numSamples; int sampleID = 0; unsigned int framesize; mp4AudioSpecificConfig mp4ASC; gchar *xmmstitle; decoder = NeAACDecOpen(); mp4ff_get_decoder_config(infile, mp4track, &buffer, &bufferSize); if(NeAACDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){ goto end; } if(buffer){ framesize = 1024; if(NeAACDecAudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0){ if(mp4ASC.frameLengthFlag == 1) framesize = 960; if(mp4ASC.sbr_present_flag == 1) framesize *= 2; } g_free(buffer); } if(channels == 0){ g_print("Number of Channels not supported\n"); goto end; } //duration = MP4GetTrackDuration(mp4file, mp4track); //msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, // duration,MP4_MSECS_TIME_SCALE); //msDuration = mp4ff_get_track_duration(infile, mp4track); //printf("%d\n", msDuration); //numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); numSamples = mp4ff_num_samples(infile, mp4track); { float f = 1024.0; if(mp4ASC.sbr_present_flag == 1) f = f * 2.0; msDuration = ((float)numSamples*(float)(f-1.0)/ (float)samplerate)*1000; } xmmstitle = getMP4title(infile, args); mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); mp4_ip.output->flush(0); mp4_ip.set_info(xmmstitle, msDuration, -1, samplerate/1000, channels); g_print("MP4 - %d channels @ %ld Hz\n", channels, samplerate); while(bPlaying){ void* sampleBuffer; faacDecFrameInfo frameInfo; gint rc; if(seekPosition!=-1){ /* duration = MP4ConvertToTrackDuration(mp4file, mp4track, seekPosition*1000, MP4_MSECS_TIME_SCALE); sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); */ float f = 1024.0; if(mp4ASC.sbr_present_flag == 1) f = f * 2.0; sampleID = (float)seekPosition*(float)samplerate/(float)(f-1.0); mp4_ip.output->flush(seekPosition*1000); seekPosition = -1; } buffer=NULL; bufferSize=0; rc = mp4ff_read_sample(infile, mp4track, sampleID++, &buffer, &bufferSize); //g_print("%d/%d\n", sampleID-1, numSamples); if((rc==0) || (buffer== NULL)){ g_print("MP4: read error\n"); sampleBuffer = NULL; sampleID=0; mp4_ip.output->buffer_free(); goto end; }else{ sampleBuffer = NeAACDecDecode(decoder, &frameInfo, buffer, bufferSize); if(frameInfo.error > 0){ g_print("MP4: %s\n", faacDecGetErrorMessage(frameInfo.error)); goto end; } if(buffer){ g_free(buffer); buffer=NULL; bufferSize=0; } while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) xmms_usleep(30000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_NE, channels, frameInfo.samples<<1, sampleBuffer); mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1); if(sampleID >= numSamples){ break; } } while(bPlaying && mp4_ip.output->buffer_playing() && mp4_ip.output->buffer_free()){ xmms_usleep(10000); } end: mp4_ip.output->close_audio(); g_free(args); NeAACDecClose(decoder); if(infile) mp4ff_close(infile); if(mp4cb) g_free(mp4cb); bPlaying = FALSE; fclose(mp4file); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }else{ // WE ARE READING AN AAC FILE FILE *file = NULL; NeAACDecHandle decoder = 0; guchar *buffer = 0; gulong bufferconsumed = 0; gulong samplerate = 0; guchar channels; gulong buffervalid = 0; TitleInput* input; gchar *temp = g_strdup(args); gchar *ext = strrchr(temp, '.'); gchar *xmmstitle = NULL; NeAACDecConfigurationPtr config; if((file = fopen(args, "rb")) == 0){ g_print("AAC: can't find file %s\n", args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((decoder = NeAACDecOpen()) == NULL){ g_print("AAC: Open Decoder Error\n"); fclose(file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } config = NeAACDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 0; NeAACDecSetConfiguration(decoder, config); if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ g_print("AAC: error g_malloc\n"); fclose(file); bPlaying = FALSE; NeAACDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ g_print("AAC: Error reading file\n"); g_free(buffer); fclose(file); bPlaying = FALSE; NeAACDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } XMMS_NEW_TITLEINPUT(input); input->file_name = g_basename(temp); input->file_ext = ext ? ext+1 : NULL; input->file_path = temp; if(!strncmp(buffer, "ID3", 3)){ gint size = 0; fseek(file, 0, SEEK_SET); size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; size+=10; fread(buffer, 1, size, file); buffervalid = fread(buffer, 1, BUFFER_SIZE, file); } xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); if(xmmstitle == NULL) xmmstitle = g_strdup(input->file_name); if(temp) g_free(temp); if(input->performer) g_free(input->performer); if(input->album_name) g_free(input->album_name); if(input->track_name) g_free(input->track_name); if(input->genre) g_free(input->genre); g_free(input); bufferconsumed = NeAACDecInit(decoder, buffer, buffervalid, &samplerate, &channels); if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ g_print("AAC: Output Error\n"); g_free(buffer); buffer=0; faacDecClose(decoder); fclose(file); mp4_ip.output->close_audio(); /* if(positionTable){ g_free(positionTable); positionTable=0; } */ g_free(xmmstitle); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } //if(bSeek){ //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); //}else{ mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); //} mp4_ip.output->flush(0); while(bPlaying && buffervalid > 0){ NeAACDecFrameInfo finfo; unsigned long samplesdecoded; char* sample_buffer = NULL; /* if(bSeek && seekPosition!=-1){ fseek(file, positionTable[seekPosition], SEEK_SET); bufferconsumed=0; buffervalid = fread(buffer, 1, BUFFER_SIZE, file); aac_ip.output->flush(seekPosition*1000); seekPosition=-1; } */ if(bufferconsumed > 0){ memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); buffervalid -= bufferconsumed; buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file); bufferconsumed = 0; } sample_buffer = NeAACDecDecode(decoder, &finfo, buffer, buffervalid); if(finfo.error){ config = NeAACDecGetCurrentConfiguration(decoder); if(config->useOldADTSFormat != 1){ NeAACDecClose(decoder); decoder = NeAACDecOpen(); config = NeAACDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 1; NeAACDecSetConfiguration(decoder, config); finfo.bytesconsumed=0; finfo.samples = 0; NeAACDecInit(decoder, buffer, buffervalid, &samplerate, &channels); }else{ g_print("FAAD2 Warning %s\n", NeAACDecGetErrorMessage(finfo.error)); buffervalid = 0; } } bufferconsumed += finfo.bytesconsumed; samplesdecoded = finfo.samples; if((samplesdecoded<=0) && !sample_buffer){ g_print("AAC: error sample decoding\n"); continue; } while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ xmms_usleep(10000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer); mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); } while(bPlaying && mp4_ip.output->buffer_playing()){ xmms_usleep(10000); } mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); bPlaying = FALSE; g_free(buffer); NeAACDecClose(decoder); g_free(xmmstitle); fclose(file); seekPosition = -1; /* if(positionTable){ g_free(positionTable); positionTable=0; } */ bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }
namespace Wiimote { static InputPlugin g_plugin(WIIMOTE_INI_NAME, _trans("Wiimote"), "Wiimote"); InputPlugin *GetPlugin() { return &g_plugin; } void Shutdown() { std::vector<ControllerEmu*>::const_iterator i = g_plugin.controllers.begin(), e = g_plugin.controllers.end(); for ( ; i!=e; ++i ) delete *i; g_plugin.controllers.clear(); WiimoteReal::Shutdown(); g_controller_interface.Shutdown(); } // if plugin isn't initialized, init and load config void Initialize(void* const hwnd, bool wait) { // add 4 wiimotes for (unsigned int i = WIIMOTE_CHAN_0; i<MAX_BBMOTES; ++i) g_plugin.controllers.push_back(new WiimoteEmu::Wiimote(i)); g_controller_interface.SetHwnd(hwnd); g_controller_interface.Initialize(); g_plugin.LoadConfig(false); WiimoteReal::Initialize(wait); // reload Wiimotes with our settings if (Movie::IsPlayingInput() || Movie::IsRecordingInput()) Movie::ChangeWiiPads(); } void Resume() { WiimoteReal::Resume(); } void Pause() { WiimoteReal::Pause(); } // __________________________________________________________________________________________________ // Function: ControlChannel // Purpose: An L2CAP packet is passed from the Core to the Wiimote, // on the HID CONTROL channel. // // Inputs: _number [Description needed] // _channelID [Description needed] // _pData [Description needed] // _Size [Description needed] // // Output: none // void ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) { if (WIIMOTE_SRC_HYBRID & g_wiimote_sources[_number]) ((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->ControlChannel(_channelID, _pData, _Size); } // __________________________________________________________________________________________________ // Function: InterruptChannel // Purpose: An L2CAP packet is passed from the Core to the Wiimote, // on the HID INTERRUPT channel. // // Inputs: _number [Description needed] // _channelID [Description needed] // _pData [Description needed] // _Size [Description needed] // // Output: none // void InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size) { if (WIIMOTE_SRC_HYBRID & g_wiimote_sources[_number]) ((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->InterruptChannel(_channelID, _pData, _Size); } // __________________________________________________________________________________________________ // Function: Update // Purpose: This function is called periodically by the Core. // TODO: Explain why. // input: _number: [Description needed] // output: none // void Update(int _number) { //PanicAlert( "Wiimote_Update" ); // TODO: change this to a try_to_lock, and make it give empty input on failure std::lock_guard<std::recursive_mutex> lk(g_plugin.controls_lock); static int _last_number = 4; if (_number <= _last_number) { g_controller_interface.UpdateOutput(); g_controller_interface.UpdateInput(); } _last_number = _number; if (WIIMOTE_SRC_EMU & g_wiimote_sources[_number]) ((WiimoteEmu::Wiimote*)g_plugin.controllers[_number])->Update(); else WiimoteReal::Update(_number); } // __________________________________________________________________________________________________ // Function: GetAttached // Purpose: Get mask of attached pads (eg: controller 1 & 4 -> 0x9) // input: none // output: The number of attached pads // unsigned int GetAttached() { unsigned int attached = 0; for (unsigned int i=0; i<MAX_BBMOTES; ++i) if (g_wiimote_sources[i]) attached |= (1 << i); return attached; } // ___________________________________________________________________________ // Function: DoState // Purpose: Saves/load state // input/output: ptr: [Description Needed] // input: mode [Description needed] // void DoState(u8 **ptr, PointerWrap::Mode mode) { // TODO: PointerWrap p(ptr, mode); for (unsigned int i=0; i<MAX_BBMOTES; ++i) ((WiimoteEmu::Wiimote*)g_plugin.controllers[i])->DoState(p); } // ___________________________________________________________________________ // Function: EmuStateChange // Purpose: Notifies the plugin of a change in emulation state // input: newState - The new state for the Wiimote to change to. // output: none // void EmuStateChange(EMUSTATE_CHANGE newState) { // TODO WiimoteReal::StateChange(newState); } }
static void play_file(char *filename) { int channelcnt = 1; FILE *f; struct xmp_options *opt; int lret; GtkTextIter start, end; AFormat fmt; int nch; opt = xmp_get_options(ctx); _D("play_file: %s", filename); stop(); /* sanity check */ if ((f = fopen(filename,"rb")) == 0) { playing = 0; return; } fclose(f); gtk_text_buffer_get_start_iter(text1b, &start); gtk_text_buffer_get_end_iter(text1b, &end); gtk_text_buffer_delete(text1b, &start, &end); xmp_plugin_audio_error = FALSE; playing = 1; opt->resol = 8; opt->verbosity = 3; opt->drv_id = "callback"; switch (xmp_cfg.mixing_freq) { case 1: opt->freq = 22050; /* 1:2 mixing freq */ break; case 2: opt->freq = 11025; /* 1:4 mixing freq */ break; default: opt->freq = 44100; /* standard mixing freq */ break; } if (xmp_cfg.force8bit == 0) opt->resol = 16; if (xmp_cfg.force_mono == 0) { channelcnt = 2; opt->outfmt &= ~XMP_FMT_MONO; } else { opt->outfmt |= XMP_FMT_MONO; } if (xmp_cfg.interpolation == 1) opt->flags |= XMP_CTL_ITPT; else opt->flags &= ~XMP_CTL_ITPT; if (xmp_cfg.filter == 1) opt->flags |= XMP_CTL_FILTER; else opt->flags &= ~XMP_CTL_FILTER; opt->mix = xmp_cfg.pan_amplitude; fmt = opt->resol == 16 ? FMT_S16_NE : FMT_U8; nch = opt->outfmt & XMP_FMT_MONO ? 1 : 2; if (audio_open) xmp_ip.output->close_audio(); if (!xmp_ip.output->open_audio(fmt, opt->freq, nch)) { xmp_plugin_audio_error = TRUE; return; } audio_open = TRUE; xmp_open_audio(ctx); pipe(fd_info); fd_old2 = dup (fileno (stderr)); dup2(fd_info[1], fileno (stderr)); fflush(stderr); pthread_create(&catch_thread, NULL, catch_info, NULL); _D("*** loading: %s", filename); pthread_mutex_lock(&load_mutex); lret = xmp_load_module(ctx, filename); pthread_mutex_unlock(&load_mutex); if (lret < 0) { xmp_ip.set_info_text("Error loading mod"); playing = 0; return; } _D("joining catch thread"); pthread_join(catch_thread, NULL); _D("joined"); dup2(fileno(stderr), fd_old2); gtk_adjustment_set_value(GTK_TEXT_VIEW(text1)->vadjustment, 0.0); close(fd_info[0]); close(fd_info[1]); _D ("before panel update"); xmp_cfg.time = lret; //xmpi_scan_module((struct xmp_context *)ctx); xmp_get_module_info(ctx, &ii->mi); strcpy(ii->filename, ""); new_module = 1; _D("after panel update"); memcpy(&xmp_cfg.mod_info, &ii->mi, sizeof (ii->mi)); xmp_ip.set_info(ii->mi.name, lret, 0, opt->freq, channelcnt); pthread_create(&decode_thread, NULL, play_loop, NULL); }
static void *mp4Decode(void *args) { MP4FileHandle mp4file; pthread_mutex_lock(&mutex); seekPosition = -1; bPlaying = TRUE; if(!(mp4file = MP4Read(args, 0))){ mp4cfg.file_type = FILE_AAC; MP4Close(mp4file); }else{ mp4cfg.file_type = FILE_MP4; } if(mp4cfg.file_type == FILE_MP4){ // We are reading a MP4 file gint mp4track; if((mp4track = getAACTrack(mp4file)) < 0){ //TODO: check here for others Audio format..... g_print("Unsupported Audio track type\n"); g_free(args); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ faacDecHandle decoder; unsigned char *buffer = NULL; guint bufferSize = 0; gulong samplerate; guchar channels; guint avgBitrate; MP4Duration duration; gulong msDuration; MP4SampleId numSamples; MP4SampleId sampleID = 1; decoder = faacDecOpen(); MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); if(!buffer){ g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){ g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } g_free(buffer); if(channels == 0){ g_print("Number of Channels not supported\n"); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } duration = MP4GetTrackDuration(mp4file, mp4track); msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, MP4_MSECS_TIME_SCALE); numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); mp4_ip.output->flush(0); mp4_ip.set_info(args, msDuration, -1, samplerate/1000, channels); g_print("MP4 - %d channels @ %d Hz\n", channels, samplerate); while(bPlaying){ void* sampleBuffer; faacDecFrameInfo frameInfo; gint rc; if(seekPosition!=-1){ duration = MP4ConvertToTrackDuration(mp4file, mp4track, seekPosition*1000, MP4_MSECS_TIME_SCALE); sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); mp4_ip.output->flush(seekPosition*1000); seekPosition = -1; } buffer=NULL; bufferSize=0; if(sampleID > numSamples){ mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, NULL, NULL, NULL, NULL); //g_print("%d/%d\n", sampleID-1, numSamples); if((rc==0) || (buffer== NULL)){ g_print("MP4: read error\n"); sampleBuffer = NULL; sampleID=0; mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); if(frameInfo.error > 0){ g_print("MP4: %s\n", faacDecGetErrorMessage(frameInfo.error)); mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if(buffer){ g_free(buffer); buffer=NULL; bufferSize=0; } while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) xmms_usleep(30000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_NE, channels, frameInfo.samples<<1, sampleBuffer); mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1); } while(bPlaying && mp4_ip.output->buffer_free()){ xmms_usleep(10000); } mp4_ip.output->close_audio(); g_free(args); faacDecClose(decoder); MP4Close(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } } else{ // WE ARE READING AN AAC FILE FILE *file = NULL; faacDecHandle decoder = 0; guchar *buffer = 0; gulong bufferconsumed = 0; gulong samplerate = 0; guchar channels; gulong buffervalid = 0; TitleInput* input; gchar *temp = g_strdup(args); gchar *ext = strrchr(temp, '.'); gchar *xmmstitle = NULL; faacDecConfigurationPtr config; if((file = fopen(args, "rb")) == 0){ g_print("AAC: can't find file %s\n", args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((decoder = faacDecOpen()) == NULL){ g_print("AAC: Open Decoder Error\n"); fclose(file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } config = faacDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 0; faacDecSetConfiguration(decoder, config); if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ g_print("AAC: error g_malloc\n"); fclose(file); bPlaying = FALSE; faacDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ g_print("AAC: Error reading file\n"); g_free(buffer); fclose(file); bPlaying = FALSE; faacDecClose(decoder); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } XMMS_NEW_TITLEINPUT(input); input->file_name = g_basename(temp); input->file_ext = ext ? ext+1 : NULL; input->file_path = temp; if(!strncmp(buffer, "ID3", 3)){ gint size = 0; fseek(file, 0, SEEK_SET); size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; size+=10; fread(buffer, 1, size, file); buffervalid = fread(buffer, 1, BUFFER_SIZE, file); } xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); if(xmmstitle == NULL) xmmstitle = g_strdup(input->file_name); if(temp) g_free(temp); if(input->performer) g_free(input->performer); if(input->album_name) g_free(input->album_name); if(input->track_name) g_free(input->track_name); if(input->genre) g_free(input->genre); g_free(input); bufferconsumed = faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels); if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ g_print("AAC: Output Error\n"); g_free(buffer); buffer=0; faacDecClose(decoder); fclose(file); mp4_ip.output->close_audio(); /* if(positionTable){ g_free(positionTable); positionTable=0; } */ g_free(xmmstitle); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } //if(bSeek){ //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); //}else{ mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); //} mp4_ip.output->flush(0); while(bPlaying && buffervalid > 0){ faacDecFrameInfo finfo; unsigned long samplesdecoded; char* sample_buffer = NULL; /* if(bSeek && seekPosition!=-1){ fseek(file, positionTable[seekPosition], SEEK_SET); bufferconsumed=0; buffervalid = fread(buffer, 1, BUFFER_SIZE, file); aac_ip.output->flush(seekPosition*1000); seekPosition=-1; } */ if(bufferconsumed > 0){ memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); buffervalid -= bufferconsumed; buffervalid += fread(&buffer[buffervalid], 1, BUFFER_SIZE-buffervalid, file); bufferconsumed = 0; } sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); if(finfo.error){ config = faacDecGetCurrentConfiguration(decoder); if(config->useOldADTSFormat != 1){ faacDecClose(decoder); decoder = faacDecOpen(); config = faacDecGetCurrentConfiguration(decoder); config->useOldADTSFormat = 1; faacDecSetConfiguration(decoder, config); finfo.bytesconsumed=0; finfo.samples = 0; faacDecInit(decoder, buffer, buffervalid, &samplerate, &channels); }else{ g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); buffervalid = 0; } } bufferconsumed += finfo.bytesconsumed; samplesdecoded = finfo.samples; if((samplesdecoded<=0) && !sample_buffer){ g_print("AAC: error sample decoding\n"); continue; } while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ xmms_usleep(10000); } mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), FMT_S16_LE, channels, samplesdecoded<<1, sample_buffer); mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); } while(bPlaying && mp4_ip.output->buffer_playing()){ xmms_usleep(10000); } mp4_ip.output->buffer_free(); mp4_ip.output->close_audio(); bPlaying = FALSE; g_free(buffer); faacDecClose(decoder); g_free(xmmstitle); fclose(file); seekPosition = -1; /* if(positionTable){ g_free(positionTable); positionTable=0; } */ bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } }
static void * play_loop(void *arg) { nsf_t * nsf = app.nsf; pdebug("nsf : play-thread\n"); if (!app.nsf) { going = FALSE; } pdebug("nsf : going [%s]\n", going ? "Yes" : "No"); app.cur_track = 0; nsf->cur_frame = nsf->cur_frame_end = 0; while (going) { if (nsf->cur_frame >= nsf->cur_frame_end) { int next_track = app.cur_track+1; pdebug("nsf : frame elapsed [%u > %u] -> track #%02d\n", nsf->cur_frame,nsf->cur_frame_end, next_track); if (next_track > app.n_tracks) { pdebug("nsf : reach last song\n"); going = FALSE; break; } SetChangeTrack(next_track, -1); } if (ApplyChangeTrack() < 0) { going = FALSE; break; } if (!app.bufcnt) { /* Run a frame. */ nsf_frame(nsf); apu_process(app.buffer, app.buflen); app.bufptr = app.buffer; app.bufcnt = app.buflen; } if (going) { int tosend = app.bufcnt << 1; while (nosefart_ip.output->buffer_free() < tosend && going) { xmms_usleep(30000); } nosefart_ip.add_vis_pcm(nosefart_ip.output->written_time(), FMT_S16_LE, 1, tosend, app.bufptr); nosefart_ip.output->write_audio(app.bufptr, tosend); tosend >>= 1; app.bufcnt -= tosend; app.bufptr += tosend; } } pdebug("nsf : decoder loop end\n"); SetChangeTrack(0, -1); ApplyChangeTrack(); if (app.nsf) { nsf_free(&app.nsf); app.nsf = nsf = 0; } /* Make sure the output plugin stops prebuffering */ if (nosefart_ip.output) { pdebug("nsf : free audio buffer.\n"); nosefart_ip.output->buffer_free(); } going = FALSE; pdebug("nsf : decode finish\n"); play_thread = 0; pthread_exit(NULL); }