示例#1
0
static THREAD_ENTRY _audioThread(void* context) {
	struct mPSP2AudioContext* audio = (struct mPSP2AudioContext*) context;
	uint32_t zeroBuffer[PSP2_SAMPLES] = {0};
	void* buffer = zeroBuffer;
	int audioPort = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, PSP2_SAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO);
	while (audio->running) {
		MutexLock(&audio->mutex);
		if (buffer != zeroBuffer) {
			// Can only happen in successive iterations
			audio->samples -= PSP2_SAMPLES;
			ConditionWake(&audio->cond);
		}
		if (audio->samples >= PSP2_SAMPLES) {
			buffer = &audio->buffer[audio->readOffset];
			audio->readOffset += PSP2_SAMPLES;
			if (audio->readOffset >= PSP2_AUDIO_BUFFER_SIZE) {
				audio->readOffset = 0;
			}
			// Don't mark samples as read until the next loop iteration to prevent
			// writing to the buffer while being read (see above)
		} else {
			buffer = zeroBuffer;
		}
		MutexUnlock(&audio->mutex);

		sceAudioOutOutput(audioPort, buffer);
	}
	sceAudioOutReleasePort(audioPort);
	return 0;
}
static int streamThread(unsigned int args, void* arg){

	int vol, dec_vol;

	for(;;) {

		// A pretty bad way to close thread
		if(termStream){
			termStream = false;
			if (bgm_chn != 0xDEAD){
				sceAudioOutReleasePort(bgm_chn);
				bgm_chn = 0xDEAD;
			}
			sceKernelExitDeleteThread(0);
		}

		sceKernelWaitSema(BGM_Mutex, 1, NULL);
		if (BGM == NULL || (!BGM->isPlaying)){
			sceKernelSignalSema(BGM_Mutex, 1);
			continue;
		}

		// Seems like audio ports are thread dependant on PSVITA :/
		if (BGM->isNewTrack){
			uint8_t audio_mode = BGM->isStereo ? SCE_AUDIO_OUT_MODE_STEREO : SCE_AUDIO_OUT_MODE_MONO;
			int nsamples = AUDIO_BUFSIZE / ((audio_mode+1)<<1);
			if (bgm_chn == 0xDEAD) bgm_chn = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, nsamples, 48000, audio_mode);
			sceAudioOutSetConfig(bgm_chn, nsamples, 48000, audio_mode);
			vol = BGM->vol * 327;
			int vol_stereo[] = {vol, vol};
			sceAudioOutSetVolume(bgm_chn, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);
			BGM->isNewTrack = false;
		}

		// Volume changes support
		dec_vol = audio_decoder->GetVolume();
		if (dec_vol != vol){
			vol = dec_vol * 327;
			int vol_stereo[] = {vol, vol};
			sceAudioOutSetVolume(bgm_chn, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);
			vol = dec_vol;
		}


		// Audio streaming feature
		if (BGM->handle != NULL){
			if (BGM->cur_audiobuf == BGM->audiobuf) BGM->cur_audiobuf = BGM->audiobuf2;
			else BGM->cur_audiobuf = BGM->audiobuf;
			audio_decoder->Decode(BGM->cur_audiobuf, AUDIO_BUFSIZE);
			if (audio_decoder->GetLoopCount() > 0){ // EoF
				BGM->endedOnce = true;
			}
			int res = sceAudioOutOutput(bgm_chn, BGM->cur_audiobuf);
			if (res < 0) Output::Error("An error occurred in audio thread (0x%lX)", res);
		}

		sceKernelSignalSema(BGM_Mutex, 1);

	}
}
示例#3
0
static void VITAAUD_PlayDevice(_THIS)
{
    Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];

    int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
    sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
    sceAudioOutOutput(this->hidden->channel, mixbuf);

    this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
}
示例#4
0
static inline int play_blocking(unsigned int channel,
                                unsigned int vol1,
                                unsigned int vol2,
                                void *buf)
{
  if (!sound_ready) return -1;
  if (channel >= AUDIO_CHANNELS) return -1;
  int vols[2]={vol1,vol2};
  sceAudioOutSetVolume(sound_stream[channel].sound_ch_handle,PSP2_AUDIO_VOLUME_FLAG_L_CH|PSP2_AUDIO_VOLUME_FLAG_R_CH,vols);
  return sceAudioOutOutput(sound_stream[channel].sound_ch_handle, buf);
}
示例#5
0
/***
 * Outputs the given audio data, in a blocking fashion.
 */
static int output_audio_blocking(unsigned int channel, unsigned int vol1, unsigned int vol2, void *buf, int length)
{
    if (channel >= AUDIO_CHANNELS) 
        return -1;

    if (vol1 > PSP_AUDIO_MAX_VOLUME) 
        vol1 = PSP_AUDIO_MAX_VOLUME;

    if (vol2 > PSP_AUDIO_MAX_VOLUME) 
        vol2 = PSP_AUDIO_MAX_VOLUME;

    int vols[2] = { vol1, vol2 };
    sceAudioOutSetConfig(audio_status[channel].Handle, length, -1, -1);
    sceAudioOutSetVolume(audio_status[channel].Handle, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols);

    return sceAudioOutOutput(audio_status[channel].Handle, buf);
}
示例#6
0
static int audioMainLoop(SceSize args, void* argp)
{
    psp_audio_t* psp = *((psp_audio_t**)argp);

#ifdef VITA
    int port = sceAudioOutOpenPort(PSP2_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT,
                                   psp->rate, PSP2_AUDIO_OUT_MODE_STEREO);
#else
    sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2);
#endif

    while (psp->running)
    {
        /* Get a non-volatile copy. */
        uint16_t readPos = psp->readPos;
        bool cond        = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK)
                           < (AUDIO_OUT_COUNT * 2);

#ifdef VITA
        sceAudioOutOutput(port,
                          cond ? psp->zeroBuffer : (psp->buffer + readPos));
#else
        sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer)
                                  : (psp->buffer + readPos));
#endif

        if (!cond)
        {
            readPos += AUDIO_OUT_COUNT;
            readPos &= AUDIO_BUFFER_SIZE_MASK;
            psp->readPos = readPos;
        }
    }

#ifdef VITA
    sceAudioOutReleasePort(port);
#else
    sceAudioSRCChRelease();
#endif
    sceKernelExitThread(0);
    return 0;
}
示例#7
0
// Audio thread code
static int bgmThread(unsigned int args, void* arg){
	
	// Initializing audio port
	int ch = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, NSAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO);
	sceAudioOutSetConfig(ch, -1, -1, -1);
	old_vol = bgmvolume.value;
	int vol = 32767 * bgmvolume.value;
	int vol_stereo[] = {vol, vol};
	sceAudioOutSetVolume(ch, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);
	
	DecodedMusic* mus;
	for (;;){
		
		// Waiting for an audio output request
		sceKernelWaitSema(Audio_Mutex, 1, NULL);
		
		// Fetching track
		mus = BGM;
		
		// Checking if a new track is available
		if (mus == NULL){
			
			//If we enter here, we probably are in the exiting procedure
			if (mustExit){
				sceAudioOutReleasePort(ch);
				mustExit = false;
				sceKernelExitDeleteThread(0);
			}
		
		}
		
		// Initializing audio decoder
		audio_decoder = AudioDecoder::Create(mus->handle, "Track");
		audio_decoder->Open(mus->handle);
		audio_decoder->SetLooping(mus->loop);
		audio_decoder->SetFormat(48000, AudioDecoder::Format::S16, 2);
		
		// Initializing audio buffers
		mus->audiobuf = (uint8_t*)malloc(BUFSIZE);
		mus->audiobuf2 = (uint8_t*)malloc(BUFSIZE);
		mus->cur_audiobuf = mus->audiobuf;
		
		// Audio playback loop
		for (;;){
		
			// Check if the music must be paused
			if (mus->pauseTrigger || mustExit){
			
				// Check if the music must be closed
				if (mus->closeTrigger){
					free(mus->audiobuf);
					free(mus->audiobuf2);
					audio_decoder.reset();
					free(mus);
					BGM = NULL;
					if (!mustExit){
						sceKernelSignalSema(Talk_Mutex, 1);
						break;
					}
				}
				
				// Check if the thread must be closed
				if (mustExit){
				
					// Check if the audio stream has already been closed
					if (mus != NULL){
						mus->closeTrigger = true;
						continue;
					}
					
					// Recursively closing all the threads
					sceAudioOutReleasePort(ch);
					mustExit = false;
					sceKernelExitThread(0);
					
				}
			
				mus->isPlaying = !mus->isPlaying;
				mus->pauseTrigger = false;
			}
			
			// Check if a volume change is required
			if (mus->changeVol){
				old_vol = bgmvolume.value;
				int vol = 32767 * bgmvolume.value;
				int vol_stereo[] = {vol, vol};
				sceAudioOutSetVolume(ch, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);
				mus->changeVol = false;
			}
			
			if (mus->isPlaying){
				
				// Check if audio playback finished
				if ((!mus->loop) && audio_decoder->IsFinished()) mus->isPlaying = false;
				
				// Update audio output
				if (mus->cur_audiobuf == mus->audiobuf) mus->cur_audiobuf = mus->audiobuf2;
				else mus->cur_audiobuf = mus->audiobuf;
				audio_decoder->Decode(mus->cur_audiobuf, BUFSIZE);	
				sceAudioOutOutput(ch, mus->cur_audiobuf);
				
			}
			
		}
		
	}
	
}
示例#8
0
static int audioMainLoop(SceSize args, void* argp)
{
   psp_audio_t* psp = *((psp_audio_t**)argp);

#ifdef VITA
   int port = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, AUDIO_OUT_COUNT,
      psp->rate, SCE_AUDIO_OUT_MODE_STEREO);
#else
   sceAudioSRCChReserve(AUDIO_OUT_COUNT, psp->rate, 2);
#endif

   while (psp->running)
   {
#ifdef VITA
      
      //sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT);

      sceKernelLockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1, 0);
      uint16_t readPos = psp->readPos;
      uint16_t readPos2 = psp->readPos;
      bool cond        = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK)
            < (AUDIO_OUT_COUNT * 2);
      if (!cond)
      {
         readPos += AUDIO_OUT_COUNT;
         readPos &= AUDIO_BUFFER_SIZE_MASK;
         psp->readPos = readPos;
      }
      sceKernelUnlockLwMutex((struct SceKernelLwMutexWork*)&psp->lock, 1);
      sceKernelSignalLwCond(&psp->cond);
      
      sceAudioOutOutput(port,
        cond ? (psp->zeroBuffer)
              : (psp->buffer + readPos2));
              
      
#else
      /* Get a non-volatile copy. */
      uint16_t readPos = psp->readPos;
      bool cond        = ((uint16_t)(psp->writePos - readPos) & AUDIO_BUFFER_SIZE_MASK)
            < (AUDIO_OUT_COUNT * 2);

      sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, cond ? (psp->zeroBuffer)
            : (psp->buffer + readPos));

      if (!cond)
      {
         readPos += AUDIO_OUT_COUNT;
         readPos &= AUDIO_BUFFER_SIZE_MASK;
         psp->readPos = readPos;
      }

#endif

   }

#ifdef VITA
   sceAudioOutReleasePort(port);
#else
   sceAudioSRCChRelease();
   sceKernelExitThread(0);
#endif
   return 0;
}
static int sfxThread(unsigned int args, void* arg){
	int ch = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, 64, 48000, SCE_AUDIO_OUT_MODE_STEREO);
	if (ch < 0){
		Output::Warning("SFX Thread: Cannot open audio port");
		sceKernelExitDeleteThread(0);
	}

	for (;;){
		sceKernelWaitSema(SFX_Mutex, 1, NULL);

		// Check if the thread must be closed
		if (mustExit){
			sfx_exited++;
			if (sfx_exited < AUDIO_CHANNELS) sceKernelSignalSema(SFX_Mutex, 1);
			else mustExit = false;
			sceAudioOutReleasePort(ch);
			sceKernelExitDeleteThread(0);
		}

		// Pick the next SE that wants to be played
		sceKernelWaitSema(SFX_Mutex_ID, 1, NULL);
		int idx = -1;
		for (int i = 0; i < AUDIO_CHANNELS; ++i) {
			if (!sfx_sounds[i].isPlaying && !sfx_sounds[i].isFinished) {
				idx = i;
				break;
			}
		}

		if (idx == -1) {
			sceKernelSignalSema(SFX_Mutex_ID, 1);
			// Shouldn't happen...
			Output::Warning("No pending SE found");
			continue;
		} else {
			sfx_sounds[idx].isPlaying = true;
			sceKernelSignalSema(SFX_Mutex_ID, 1);
		}

		DecodedSound& sfx = sfx_sounds[idx];

		// Preparing audio port
		uint8_t audio_mode = sfx.isStereo ? SCE_AUDIO_OUT_MODE_STEREO : SCE_AUDIO_OUT_MODE_MONO;
		int nsamples = AUDIO_BUFSIZE / ((audio_mode+1)<<1);
		sceAudioOutSetConfig(ch, nsamples, 48000, audio_mode);
		int vol = sfx.decoder->GetVolume() * 327;
		int vol_stereo[] = {vol, vol};
		sceAudioOutSetVolume(ch, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vol_stereo);

		// Playing sound
		while (!sfx.isFinished){
			if (sfx.cur_audiobuf == sfx.audiobuf) sfx.cur_audiobuf = sfx.audiobuf2;
			else sfx.cur_audiobuf = sfx.audiobuf;
			sfx.decoder->Decode(sfx.cur_audiobuf, AUDIO_BUFSIZE);
			sceAudioOutOutput(ch, sfx.cur_audiobuf);
			if (sfx.decoder->IsFinished()) { // EoF
				// SE slot is free again
				sfx.isFinished = true;
				break;
			}
		}
	}

}