예제 #1
0
파일: win_snd.c 프로젝트: HipsterLion/SRB2
// Callback hook to read streaming GME data.
static FMOD_RESULT F_CALLBACK GMEReadCallback(FMOD_SOUND *sound, void *data, unsigned int datalen)
{
	Music_Emu *emu;
	void *emuvoid = NULL;
	// get our emu
	FMR(FMOD_Sound_GetUserData(sound, &emuvoid));
	emu = emuvoid;
	// no emu? no play.
	if (!emu)
		return FMOD_ERR_FILE_EOF;
	if (gme_track_ended(emu))
	{
		// don't delete the primary music stream
		if (emu == gme)
			return FMOD_ERR_FILE_EOF;
		// do delete sfx streams
		FMR(FMOD_Sound_SetUserData(sound, NULL));
		gme_delete(emu);
		return FMOD_ERR_FILE_EOF;
	}
	// play beautiful musics theme of ancient land.
	if (gme_play(emu, datalen/2, data))
		return FMOD_ERR_FILE_BAD;
	// O.K
	return FMOD_OK;
}
예제 #2
0
파일: GME.cpp 프로젝트: biddyweb/QMPlay2
bool GME::read(Packet &decoded, int &idx)
{
	if (m_aborted || gme_track_ended(m_gme))
		return false;

	gme_set_fade(m_gme, (m_length - 8) * 1000); //Set every time to avoid problems

	const int chunkSize = 1024 * 2; //Always stereo

	decoded.resize(chunkSize * sizeof(float));
	qint16 *srcData = (qint16 *)decoded.data();
	float *dstData = (float *)decoded.data();

	if (gme_play(m_gme, chunkSize, srcData) != NULL)
		return false;

	for (int i = chunkSize - 1; i >= 0; --i)
		dstData[i] = srcData[i] / 32768.0;

	decoded.ts = gme_tell(m_gme) / 1000.0;
	decoded.duration = chunkSize / 2 / (double)m_srate;

	idx = 0;

	return true;
}
예제 #3
0
파일: gme.c 프로젝트: 0xheart0/vlc
static int Demux (demux_t *demux)
{
    demux_sys_t *sys = demux->p_sys;

    /* Next track */
    if (gme_track_ended (sys->emu))
    {
        msg_Dbg (demux, "track %u ended", sys->track_id);
        if (++sys->track_id >= (unsigned)gme_track_count (sys->emu))
            return 0;

        demux->info.i_update |= INPUT_UPDATE_TITLE;
        demux->info.i_title = sys->track_id;
        gme_start_track (sys->emu, sys->track_id);
    }


    block_t *block = block_Alloc (2 * 2 * SAMPLES);
    if (unlikely(block == NULL))
        return 0;

    gme_err_t ret = gme_play (sys->emu, 2 * SAMPLES, (void *)block->p_buffer);
    if (ret != NULL)
    {
        block_Release (block);
        msg_Err (demux, "%s", ret);
        return 0;
    }

    block->i_pts = block->i_dts = VLC_TS_0 + date_Get (&sys->pts);
    es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
    es_out_Send (demux->out, sys->es, block);
    date_Increment (&sys->pts, SAMPLES);
    return 1;
}
예제 #4
0
파일: cgme.c 프로젝트: jubalh/deadbeef
static int
cgme_read (DB_fileinfo_t *_info, char *bytes, int size) {
    gme_fileinfo_t *info = (gme_fileinfo_t*)_info;
    float t = (size/4) / (float)_info->fmt.samplerate;
    if (_info->readpos + t >= info->duration) {
        t = info->duration - _info->readpos;
        if (t <= 0) {
            return 0;
        }
        // DON'T ajust size, buffer must always be po2
        //size = t * (float)info->samplerate * 4;
    }

    if (chip_voices_changed) {
        chip_voices = deadbeef->conf_get_int ("chip.voices", 0xff);
        chip_voices_changed = 0;
        gme_mute_voices (info->emu, chip_voices^0xff);
    }

    if (gme_play (info->emu, size/2, (short*)bytes)) {
        return 0;
    }
    if (conf_fadeout > 0 && info->duration >= conf_fadeout && info->reallength <= 0 && _info->readpos >= info->duration - conf_fadeout) {
        float fade_amnt =  (info->duration - _info->readpos) / (float)conf_fadeout;
        int nsamples = size/2;
        float fade_incr = 1.f / (_info->fmt.samplerate * conf_fadeout) * 256;
        const float ln10=2.3025850929940002f;
        float fade = exp(ln10*(-(1.f-fade_amnt) * 3));

        for (int i = 0; i < nsamples; i++) {
            ((short*)bytes)[i] *= fade;
            if (!(i & 0xff)) {
                fade_amnt += fade_incr;
                fade = exp(ln10*(-(1.f-fade_amnt) * 3));
            }
        }
    }

    _info->readpos += t;
    if (info->reallength == -1) {
        if (gme_track_ended (info->emu)) {
            return 0;
        }
    }
    return size;
}
예제 #5
0
파일: libgme.c 프로젝트: DeHackEd/FFmpeg
static int read_packet_gme(AVFormatContext *s, AVPacket *pkt)
{
    GMEContext *gme = s->priv_data;
    int n_samples = AUDIO_PKT_SIZE / 2;
    int ret;

    if (gme_track_ended(gme->music_emu))
        return AVERROR_EOF;

    if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0)
        return ret;

    if (gme_play(gme->music_emu, n_samples, (short *)pkt->data))
        return AVERROR_EXTERNAL;
    pkt->size = AUDIO_PKT_SIZE;

    return 0;
}
예제 #6
0
int GmeDecoder::decode()
{
	short *sbuf = static_cast<short*>(buffer);
	int size = bufferSize / sizeof(short);

	if (gme_play(emu, size, sbuf) != 0)
		throw love::Exception("Error while decoding game music");

	if (!eof && gme_track_ended(emu))
	{
		// Start the next track if this one ended.
		if (cur_track < num_tracks - 1)
			gme_start_track(emu, ++cur_track);
		else
			eof = true;
	}

	return bufferSize;
}
예제 #7
0
JNIEXPORT jint JNICALL Java_com_ssb_droidsound_plugins_GMEPlugin_N_1getSoundData(JNIEnv *env, jobject obj, jlong song, jshortArray bArray, int size)
{
	GMEInfo *info = (GMEInfo*)song;

	if(!info->started) {
		gme_err_t err = gme_start_track(info->emu, 0);
		info->started = true;
	}

	if(gme_track_ended(info->emu)) {
		return 0;
	}

	jshort *ptr = env->GetShortArrayElements(bArray, NULL);
	//__android_log_print(ANDROID_LOG_VERBOSE, "GMEPlugin", "Getting %d shorts from %p", size, emu);
	gme_err_t err = gme_play(info->emu, size, ptr);
	//__android_log_print(ANDROID_LOG_VERBOSE, "GMEPlugin", "Result %d", err);
	env->ReleaseShortArrayElements(bArray, ptr, 0);
	return size;
}
예제 #8
0
JNIEXPORT jint JNICALL Java_com_ssb_droidsound_plugins_GMEPlugin_N_1getSoundData(JNIEnv *env, jobject obj, jlong song, jshortArray sArray, int size)
{
	GMEInfo *info = (GMEInfo*)song;

	if(!info->started) {
		gme_err_t err = gme_start_track(info->emu, 0);
		info->started = true;
	}

	if(gme_track_ended(info->emu)) {
		return -1;
	}

	jshort *ptr = env->GetShortArrayElements(sArray, NULL);

	gme_err_t err = gme_play(info->emu, size, ptr);

	env->ReleaseShortArrayElements(sArray, ptr, 0);
	return size;
}
예제 #9
0
static int
cgme_read (DB_fileinfo_t *_info, char *bytes, int size) {
    gme_fileinfo_t *info = (gme_fileinfo_t*)_info;
    int playForever = conf_play_forever && info->can_loop;
    float t = (size/4) / (float)_info->fmt.samplerate;
    if (info->eof) {
        return 0;
    }
    if (!playForever && _info->readpos + t >= info->duration) {
        t = info->duration - _info->readpos;
        if (t <= 0) {
            return 0;
        }
        // DON'T ajust size, buffer must always be po2
        //size = t * (float)info->samplerate * 4;
    }

    if (chip_voices_changed) {
        chip_voices = deadbeef->conf_get_int ("chip.voices", 0xff);
        chip_voices_changed = 0;
        gme_mute_voices (info->emu, chip_voices^0xff);
    }

    if (playForever)
        gme_set_fade(info->emu, -1, 0);
    else
        gme_set_fade(info->emu, (int)(info->duration * 1000), conf_fadeout * 1000);

    if (gme_play (info->emu, size/2, (short*)bytes)) {
        return 0;
    }

    _info->readpos += t;
    if (gme_track_ended (info->emu)) {
        info->eof = 1;
    }
    return size;
}
예제 #10
0
/* Read some data */
static gint
xmms_gme_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err)
{
	xmms_gme_data_t *data;
	gme_err_t play_error;

	g_return_val_if_fail (xform, -1);

	data = (xmms_gme_data_t *)xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	if (gme_track_ended (data->emu))
		return 0;

	play_error = gme_play (data->emu, len/2, (short int *)buf);
	if (play_error) {
		XMMS_DBG ("gme_play returned an error: %s", play_error);
		xmms_error_set (err, XMMS_ERROR_GENERIC, play_error);
		return -1;
	}

	return len;
}
예제 #11
0
bool GMESong::Read(SoundStream *stream, void *buff, int len, void *userdata)
{
	gme_err_t err;
	GMESong *song = (GMESong *)userdata;

	song->CritSec.Enter();
	if (gme_track_ended(song->Emu))
	{
		if (song->m_Looping)
		{
			song->StartTrack(song->CurrTrack, false);
		}
		else
		{
			memset(buff, 0, len);
			song->CritSec.Leave();
			return false;
		}
	}
	err = gme_play(song->Emu, len >> 1, (short *)buff);
	song->CritSec.Leave();
	return (err == NULL);
}
예제 #12
0
static event_t *
fa_gme_playfile_internal(media_pipe_t *mp, const void *buf, size_t size,
			 char *errbuf, size_t errlen, int hold, int track,
			 const char *url)
{
  media_queue_t *mq = &mp->mp_audio;
  Music_Emu *emu;
  gme_err_t err;
  int sample_rate = 48000;
  media_buf_t *mb = NULL;
  event_t *e;
  int registered_play = 0;

  err = gme_open_data(buf, size, &emu, sample_rate);
  if(err != NULL) {
    snprintf(errbuf, errlen, "Unable to load file -- %s", err);
    return NULL;
  }

  gme_start_track(emu, track);

  mp->mp_audio.mq_stream = 0;
  mp_configure(mp, MP_PLAY_CAPS_PAUSE | MP_PLAY_CAPS_SEEK,
	       MP_BUFFER_SHALLOW, 0);
  mp_become_primary(mp);
  

  while(1) {

    if(gme_track_ended(emu)) {
      e = event_create_type(EVENT_EOF);
      break;
    }

    if(mb == NULL) {
      mb = media_buf_alloc_unlocked(mp, sizeof(int16_t) * CHUNK_SIZE * 2);
      mb->mb_data_type = MB_AUDIO;
      mb->mb_channels = 2;
      mb->mb_rate = sample_rate;
      mb->mb_pts = gme_tell(emu) * 1000;
      mb->mb_drive_clock = 1;

      if(!registered_play && mb->mb_pts > METADB_AUDIO_PLAY_THRESHOLD) {
	registered_play = 1;
	metadb_register_play(url, 1, CONTENT_AUDIO);
      }

      gme_play(emu, CHUNK_SIZE * mb->mb_channels, mb->mb_data);
    }

    if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
      mb = NULL; /* Enqueue succeeded */
      continue;
    }
    if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {
      mp_flush(mp, 0);
      break;


    } else if(event_is_type(e, EVENT_SEEK)) {

      event_ts_t *ets = (event_ts_t *)e;
      gme_seek(emu, ets->ts / 1000);
      seekflush(mp, &mb);
      
    } else if(event_is_action(e, ACTION_SKIP_BACKWARD) ||
	      event_is_action(e, ACTION_SKIP_FORWARD) ||
	      event_is_action(e, ACTION_STOP)) {
      mp_flush(mp, 0);
      break;
    }
    event_release(e);
  }  

  gme_delete(emu);

  if(mb != NULL)
    media_buf_free_unlocked(mp, mb);

  return e;
}
예제 #13
0
static event_t *
fa_gme_playfile_internal(media_pipe_t *mp, void *fh,
			 char *errbuf, size_t errlen, int hold, int track)
{
  media_queue_t *mq = &mp->mp_audio;
  Music_Emu *emu;
  gme_err_t err;
  char *buf;
  int lost_focus = 0;
  size_t size, r;
  int sample_rate = 48000;
  media_buf_t *mb = NULL;
  event_t *e;

  size = fa_fsize(fh);

  buf = malloc(size);
  r = fa_read(fh, buf, size);

  if(r != size) {
    snprintf(errbuf, errlen, "Unable to read file");
    free(buf);
    return NULL;
  }

  err = gme_open_data(buf, size, &emu, sample_rate);
  free(buf);
  if(err != NULL) {
    snprintf(errbuf, errlen, "Unable to load file -- %s", err);
    return NULL;
  }

  gme_start_track(emu, track);

  mp_set_playstatus_by_hold(mp, hold, NULL);
  mp->mp_audio.mq_stream = 0;
  mp_set_play_caps(mp, MP_PLAY_CAPS_PAUSE | MP_PLAY_CAPS_SEEK);
  mp_become_primary(mp);
  

  while(1) {

    if(gme_track_ended(emu)) {
      e = event_create_type(EVENT_EOF);
      break;
    }

    if(mb == NULL) {
      mb = media_buf_alloc();
      mb->mb_data_type = MB_AUDIO;
      mb->mb_channels = 2;
      mb->mb_size = sizeof(int16_t) * CHUNK_SIZE * mb->mb_channels;
      mb->mb_data = malloc(mb->mb_size);
      mb->mb_rate = sample_rate;
      mb->mb_time = gme_tell(emu) * 1000;
      gme_play(emu, CHUNK_SIZE * mb->mb_channels, mb->mb_data);
    }

    if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
      mb = NULL; /* Enqueue succeeded */
      continue;
    }
    if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {
      mp_flush(mp, 0);
      break;


    } else if(event_is_type(e, EVENT_SEEK)) {

      event_ts_t *ets = (event_ts_t *)e;
      gme_seek(emu, ets->pts / 1000);
      seekflush(mp, &mb);
      
    } else if(event_is_action(e, ACTION_SEEK_FAST_BACKWARD)) {

      deltaseek(mp, &mb, emu, -60000);

    } else if(event_is_action(e, ACTION_SEEK_BACKWARD)) {

      deltaseek(mp, &mb, emu, -15000);

    } else if(event_is_action(e, ACTION_SEEK_FAST_FORWARD)) {

      deltaseek(mp, &mb, emu, 60000);

    } else if(event_is_action(e, ACTION_SEEK_FORWARD)) {

      deltaseek(mp, &mb, emu, 15000);

    } else if(event_is_action(e, ACTION_PLAYPAUSE) ||
	      event_is_action(e, ACTION_PLAY) ||
	      event_is_action(e, ACTION_PAUSE)) {

      hold = action_update_hold_by_event(hold, e);
      mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
      lost_focus = 0;
      mp_set_playstatus_by_hold(mp, hold, NULL);

    } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) {

      hold = 1;
      lost_focus = 1;
      mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
      mp_set_playstatus_by_hold(mp, hold, e->e_payload);

    } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) {

      if(lost_focus) {
	hold = 0;
	lost_focus = 0;
	mp_send_cmd_head(mp, mq, MB_CTRL_PLAY);
	mp_set_playstatus_by_hold(mp, hold, NULL);
      }

    } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) {

      hold = 1;
      lost_focus = 0;
      mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
      mp_set_playstatus_by_hold(mp, hold, e->e_payload);

    } else if(event_is_action(e, ACTION_PREV_TRACK) ||
	      event_is_action(e, ACTION_NEXT_TRACK) ||
	      event_is_action(e, ACTION_STOP)) {
      mp_flush(mp, 0);
      break;
    }
    event_release(e);
  }  

  gme_delete(emu);

  if(mb != NULL)
    media_buf_free(mb);

  if(hold) { 
    // If we were paused, release playback again.
    mp_send_cmd(mp, mq, MB_CTRL_PLAY);
    mp_set_playstatus_by_hold(mp, 0, NULL);
  }
  return e;
}
예제 #14
0
파일: glue.cpp 프로젝트: Chaduke/bah.mod
int bmx_gme_track_ended(MaxMusicEmu * emu) {
	return gme_track_ended(emu->emu);
}
예제 #15
0
bool Music_Player::track_ended() const
{
	return emu_ ? gme_track_ended( emu_ ) : false;
}