int __declspec(dllexport) DLL_StartPlayback(void* nsf, int track) { nsf_playtrack((nsf_t*)nsf,track,48000,16,false); for (int i = 0; i < 6; i++) nsf_setchan((nsf_t*)nsf,i,true); return 1; }
static int SetupSong(void) { nsf_t * nsf = app.nsf; int track; if (!nsf) { pdebug("nsf : setup song, no nsf\n"); return -1; } track = app.tracks[app.cur_track].map; pdebug("nsf : setup song #%d/%d map:[%d]\n", app.cur_track, app.n_tracks, track); if (nsf_playtrack(nsf, track, 44100, 16, 0) != track) { pdebug("nsf : play-track failed\n"); return -1; } pdebug("nsf : set filter\n"); nsf_setfilter(nsf, NSF_FILTER_NONE); app.bufcnt = 0; SetInfo(); return 0; }
static void nsf_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { nsf_decoder_t *this = (nsf_decoder_t *) this_gen; audio_buffer_t *audio_buffer; if (buf->decoder_flags & BUF_FLAG_HEADER) { /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize * the decoder. The buffer element type has 4 decoder_info fields, * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field * 3 is the number of channels. */ this->sample_rate = buf->decoder_info[1]; this->bits_per_sample = buf->decoder_info[2]; this->channels = buf->decoder_info[3]; /* take this opportunity to initialize stream/meta information */ this->stream->meta_info[XINE_META_INFO_AUDIOCODEC] = strdup("NES Music (Nosefart)"); this->song_number = buf->content[4]; /* allocate a buffer for the file */ this->nsf_size = BE_32(&buf->content[0]); this->nsf_file = xine_xmalloc(this->nsf_size); this->nsf_index = 0; /* peform any other required initialization */ this->last_pts = -1; this->iteration = 0; return; } /* accumulate chunks from the NSF file until whole file is received */ if (this->nsf_index < this->nsf_size) { xine_fast_memcpy(&this->nsf_file[this->nsf_index], buf->content, buf->size); this->nsf_index += buf->size; if (this->nsf_index == this->nsf_size) { /* file has been received, proceed to initialize engine */ nsf_init(); this->nsf = nsf_load(NULL, this->nsf_file, this->nsf_size); if (!this->nsf) { printf ("nsf: could not initialize NSF\n"); /* make the decoder return on every subsequent buffer */ this->nsf_index = 0; } this->nsf->current_song = this->song_number; nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate, this->bits_per_sample, this->channels); } return; } /* if the audio output is not open yet, open the audio output */ if (!this->output_open) { this->output_open = this->stream->audio_out->open( this->stream->audio_out, this->stream, this->bits_per_sample, this->sample_rate, (this->channels == 2) ? AO_CAP_MODE_STEREO : AO_CAP_MODE_MONO); } /* if the audio still isn't open, do not go any further with the decode */ if (!this->output_open) return; /* check if a song change was requested */ if (buf->decoder_info[1]) { this->nsf->current_song = buf->decoder_info[1]; nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate, this->bits_per_sample, this->channels); } /* time to decode a frame */ if (this->last_pts != -1) { /* process a frame */ nsf_frame(this->nsf); /* get an audio buffer */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if (audio_buffer->mem_size == 0) { printf ("nsf: Help! Allocated audio buffer with nothing in it!\n"); return; } apu_process(audio_buffer->mem, this->sample_rate / this->nsf->playback_rate); audio_buffer->vpts = buf->pts; audio_buffer->num_frames = this->sample_rate / this->nsf->playback_rate; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } this->last_pts = buf->pts; }
static gboolean start_play_tune (GstNsfDec * nsfdec) { gboolean res; nsfdec->nsf = nsf_load (NULL, GST_BUFFER_DATA (nsfdec->tune_buffer), GST_BUFFER_SIZE (nsfdec->tune_buffer)); if (!nsfdec->nsf) goto could_not_load; if (!nsfdec_negotiate (nsfdec)) goto could_not_negotiate; nsfdec->taglist = gst_tag_list_new (); gst_tag_list_add (nsfdec->taglist, GST_TAG_MERGE_REPLACE, GST_TAG_AUDIO_CODEC, "NES Sound Format", NULL); if (nsfdec->nsf->artist_name) gst_tag_list_add (nsfdec->taglist, GST_TAG_MERGE_REPLACE, GST_TAG_ARTIST, nsfdec->nsf->artist_name, NULL); if (nsfdec->nsf->song_name) gst_tag_list_add (nsfdec->taglist, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE, nsfdec->nsf->song_name, NULL); gst_element_post_message (GST_ELEMENT_CAST (nsfdec), gst_message_new_tag (GST_OBJECT (nsfdec), gst_tag_list_copy (nsfdec->taglist))); nsf_playtrack (nsfdec->nsf, nsfdec->tune_number, nsfdec->frequency, nsfdec->bits, nsfdec->stereo); nsf_setfilter (nsfdec->nsf, nsfdec->filter); nsfdec->bps = (nsfdec->bits >> 3) * nsfdec->channels; /* calculate the number of bytes we need to output after each call to * nsf_frame(). */ nsfdec->blocksize = nsfdec->bps * nsfdec->frequency / nsfdec->nsf->playback_rate; gst_pad_push_event (nsfdec->srcpad, gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0)); res = gst_pad_start_task (nsfdec->srcpad, (GstTaskFunction) play_loop, nsfdec->srcpad, NULL); return res; /* ERRORS */ could_not_load: { GST_ELEMENT_ERROR (nsfdec, LIBRARY, INIT, ("Could not load tune"), ("Could not load tune")); return FALSE; } could_not_negotiate: { GST_ELEMENT_ERROR (nsfdec, CORE, NEGOTIATION, ("Could not negotiate format"), ("Could not negotiate format")); return FALSE; } }