コード例 #1
0
ファイル: libsnes.cpp プロジェクト: OV2/snes9x-libsnes
static void S9xAudioCallback(void*)
{
   S9xFinalizeSamples();
   size_t avail = S9xGetSampleCount();
   S9xMixSamples((uint8*)audio_buf, avail);
   for (size_t i = 0; i < avail; i+=2)
      s9x_audio_cb((uint16_t)audio_buf[i], (uint16_t)audio_buf[i + 1]);
}
コード例 #2
0
ファイル: libretro.c プロジェクト: RobLoach/snes9x-next
static void S9xAudioCallback()
{
   size_t avail;
   /* Just pick a big buffer. We won't use it all. */
   static int16_t audio_buf[0x10000];

   S9xFinalizeSamples();
   avail = S9xGetSampleCount();
   S9xMixSamples(audio_buf, avail);
   audio_batch_cb(audio_buf, avail >> 1);
}
コード例 #3
0
ファイル: libsnes.cpp プロジェクト: apollolux/snes9x-next
static void S9xAudioCallback()
{
   // Just pick a big buffer. We won't use it all.
   static int16_t audio_buf[0x10000];

   S9xFinalizeSamples();
   size_t avail = S9xGetSampleCount();
   S9xMixSamples(audio_buf, avail);
   for (size_t i = 0; i < avail; i+=2)
      s9x_audio_cb((uint16_t)audio_buf[i], (uint16_t)audio_buf[i + 1]);
}
コード例 #4
0
ファイル: libretro.cpp プロジェクト: AdmiralCurtiss/snes9x
static void S9xAudioCallback(void*)
{
   const int BUFFER_SIZE = 256;
   // This is called every time 128 to 132 samples are generated, which happens about 8 times per frame.  A buffer size of 256 samples is enough here.
   static int16_t audio_buf[BUFFER_SIZE];

   S9xFinalizeSamples();
   size_t avail = S9xGetSampleCount();
   while (avail >= BUFFER_SIZE)
   {
	   //this loop will never be entered, but handle oversized sample counts just in case
	   S9xMixSamples((uint8*)audio_buf, BUFFER_SIZE);
	   audio_batch_cb(audio_buf, BUFFER_SIZE >> 1);

	   avail -= BUFFER_SIZE;
   }
   if (avail > 0)
   {
	   S9xMixSamples((uint8*)audio_buf, avail);
	   audio_batch_cb(audio_buf, avail >> 1);
   }
コード例 #5
0
ファイル: iOSAudio.cpp プロジェクト: TheReflectingGod/SiOS
static void AQBufferCallback(
                             void *userdata,
                             AudioQueueRef outQ,
                             AudioQueueBufferRef outQB)
{
	outQB->mAudioDataByteSize = SI_SoundBufferSizeBytes;
  AudioQueueSetParameter(outQ, kAudioQueueParam_Volume, SI_AudioVolume);

	if(SI_EmulationPaused || !SI_EmulationRun || !SI_SoundIsInit)
  {
    SI_AudioIsOnHold = 1;
    memset(outQB->mAudioData, 0, SI_SoundBufferSizeBytes);
  }
	else
  {
    SI_AudioIsOnHold = 0;

    int available = S9xGetSampleCount()*2;
    if(available > SI_SoundBufferSizeBytes)
      available = SI_SoundBufferSizeBytes;
    
    S9xMixSamples((unsigned char*)outQB->mAudioData, available/2);
    
    if(available < SI_SoundBufferSizeBytes)
    {
      if(available == 0)
      {
        // do nothing here... we didn't copy anything... scared that if i write something to the output buffer, we'll get chirps and stuff
      }
      else
      {
        //printf("Fixing\n");
        // sounds wiggly
        memset(((unsigned char*)outQB->mAudioData)+available, ((unsigned char*)outQB->mAudioData)[available-1], SI_SoundBufferSizeBytes-available);
        // sounds a little skippedly
        //memset(((unsigned char*)outQB->mAudioData)+available, *(int*)(((unsigned char*)outQB->mAudioData)+(available-3)), SI_SoundBufferSizeBytes-available);
      }
    }
  }

	AudioQueueEnqueueBuffer(outQ, outQB, 0, NULL);
}
コード例 #6
0
ファイル: CFMODEx.cpp プロジェクト: 7sevenx7/snes9x
FMOD_RESULT F_CALLBACK CFMODEx::FMODExStreamCallback(
	  FMOD_SOUND *  sound, 
	  void *  data, 
	  unsigned int  datalen
	)
{
    int sample_count = datalen;

	sample_count >>= (Settings.SixteenBitSound?1:0);

	EnterCriticalSection(&GUI.SoundCritSect);

	S9xMixSamples((unsigned char *) data, sample_count);

	LeaveCriticalSection(&GUI.SoundCritSect);

    SetEvent(GUI.SoundSyncEvent);

    return FMOD_OK;
}
コード例 #7
0
ファイル: libspc.cpp プロジェクト: pcercuei/dcplaya
/* get samples
   ---------------------------------------------------------------- */
void SPC_update(unsigned char *buf)
{
    // APU_LOOP
    int c, ic, oc;

    BCOLOR(255, 0, 0);

    /* VP : rewrote this loop, it was completely wrong in original
       spcxmms-0.2.1 */
    for (c = 0; c < 2048000 / RATE; ) {
        oc = c;
        for (ic = c + 256; c < ic; ) {
            int cycles;
            cycles = S9xAPUCycleLengths [*IAPU.PC];
            (*S9xApuOpcodes[*IAPU.PC]) ();
            //APU_EXECUTE1();

            if (IAPU.Slowdown > 0) {
                /* VP : in slowdown mode, SPC executes 2^SPC_slowdown_cycle_shift
                   times slower */
                c += cycles << SPC_slowdown_cycle_shift;
                IAPU.Slowdown --;
            } else {
                /* VP : no slowdown, normal speed of the SPC */
                c += cycles;
            }
        }

        /* VP : Execute timer required number of times */
        for (ic = 0; ic < (c / 32) - (oc / 32) ; ic++) {
            IAPU.TimerErrorCounter ++;
            DoTimer();
        }

    }

    BCOLOR(255, 255, 0);
    S9xMixSamples ((unsigned char *)buf, samples_per_mix);
    BCOLOR(0, 0, 0);

}
コード例 #8
0
ファイル: CXAudio2.cpp プロジェクト: LAGonauta/snes8x
/*  CXAudio2::ProcessSound
The mixing function called by the sound core when new samples are available.
SoundBuffer is divided into blockCount blocks. If there are enought available samples and a free block,
the block is filled and queued to the source voice. bufferCount is increased by pushbuffer and decreased by
the OnBufferComplete callback.
*/
void CXAudio2::ProcessSound()
{
	S9xFinalizeSamples();

	if(!initDone)
		return;

	BYTE * curBuffer;

	UINT32 availableSamples;
	UINT32 availableBytes;

	availableSamples = S9xGetSampleCount();
	availableBytes = availableSamples * (Settings.SixteenBitSound ? 2 : 1);

	while(availableSamples > singleBufferSamples && bufferCount < blockCount) {
		curBuffer = soundBuffer + writeOffset;
		S9xMixSamples(curBuffer,singleBufferSamples);
		PushBuffer(singleBufferBytes,curBuffer,NULL);
		writeOffset+=singleBufferBytes;
		writeOffset%=sum_bufferSize;
	}
}
コード例 #9
0
ファイル: libspc.cpp プロジェクト: MisterZeus/SNES-Tracker
/* get samples
   ---------------------------------------------------------------- */
void SPC_update(unsigned char *buf)
{
    // APU_LOOP
    int c, ic;

#if 1
    for (c = 0; c < 2048000 / 32 / RATE; c ++) {
        for (ic = 0; ic < 32; ic ++)
            APU_EXECUTE1(); IAPU.TimerErrorCounter ++; DoTimer();
    }
#else
    for (APU.Cycles = 0; APU.Cycles < 204800 / RATE; APU.Cycles ++) {
        APU_EXECUTE1();
        ++ IAPU.TimerErrorCounter;
        if ((IAPU.TimerErrorCounter & 31) == 0)
            DoTimer();
        APURegisters.PC = IAPU.PC - IAPU.RAM;
        S9xAPUPackStatus();
    }
#endif

    S9xMixSamples ((unsigned char *)buf, samples_per_mix);
}
コード例 #10
0
ファイル: snes.cpp プロジェクト: plasma-apps/emumaster
int SnesEmu::fillAudioBuffer(char *stream, int streamSize) {
	int count = qMin(streamSize/4, soundSampleCount);
	S9xMixSamples((s16 *)stream, count * 2);
	return count * 4;
}
コード例 #11
0
ファイル: iOSAudio.cpp プロジェクト: ARival/SiOS
static void AQBufferCallback(
                             void *userdata,
                             AudioQueueRef outQ,
                             AudioQueueBufferRef outQB)
{
	outQB->mAudioDataByteSize = SI_SoundBufferSizeBytes;
  AudioQueueSetParameter(outQ, kAudioQueueParam_Volume, SI_AudioVolume);

	if(SI_EmulationPaused || !SI_EmulationRun || !SI_SoundIsInit)
  {
    SI_AudioIsOnHold = 1;
    SI_AudioOffset = 0;
    memset(outQB->mAudioData, 0, SI_SoundBufferSizeBytes);
  }
	else
  {
    SI_AudioIsOnHold = 0;

    //static int i = 0;
    //printf("willLock %i\n", i);
    //printf("locked %i\n", i);
    //i++;
    int totalSamples = S9xGetSampleCount();
    int totalBytes = totalSamples;
    int samplesToUse = totalSamples;
    int bytesToUse = totalBytes;
    if(Settings.SixteenBitSound == true)
    {
      bytesToUse *= 2;
      totalBytes *= 2;
    }
    if(bytesToUse > SI_SoundBufferSizeBytes)
    {
      bytesToUse = SI_SoundBufferSizeBytes;
      if(Settings.SixteenBitSound == true)
        samplesToUse = SI_SoundBufferSizeBytes/2;
      else
        samplesToUse = SI_SoundBufferSizeBytes;
    }
    
    // calculating the audio offset
    int samplesShouldBe = SI_SoundBufferSizeBytes;
    if(Settings.SixteenBitSound == true)
      samplesShouldBe = SI_SoundBufferSizeBytes/2;
    
    SI_AudioOffset -= (totalSamples-samplesShouldBe)*(1.0/Settings.SoundPlaybackRate)*1000-50;
    if(SI_AudioOffset > 8000)
      SI_AudioOffset = 4000;
    else if(SI_AudioOffset < -8000)
      SI_AudioOffset = -4000;
    //SI_AudioOffset = 900; // -900 is the magic number for this emulator running on iOS Simulator on my computer
    //printf("AudioOffset: %i\n", SI_AudioOffset);
  
    if(samplesToUse > 0)
      S9xMixSamples((unsigned char*)outQB->mAudioData, samplesToUse);
    
    if(bytesToUse < SI_SoundBufferSizeBytes)
    {
      if(bytesToUse == 0)
      {
        // do nothing here... we didn't copy anything... scared that if i write something to the output buffer, we'll get chirps and stuff
        //printf("0 sampes available\n");
      }
      else
      {
        //printf("Fixing %i of %i\n", bytesToUse, SI_SoundBufferSizeBytes);
        // sounds wiggly
        memset(((unsigned char*)outQB->mAudioData)+bytesToUse, ((unsigned char*)outQB->mAudioData)[bytesToUse-1], SI_SoundBufferSizeBytes-bytesToUse);
      }
    }
  }

	AudioQueueEnqueueBuffer(outQ, outQB, 0, NULL);
}
コード例 #12
0
ファイル: main.cpp プロジェクト: jeremyfry/PocketSNES
static
int Run(int sound)
{
  	int skip=0, done=0, doneLast=0,aim=0,i;
	Settings.NextAPUEnabled = Settings.APUEnabled = sound;
	sal_TimerInit(Settings.FrameTime);
	done=sal_TimerRead()-1;

	if (sound) {
		/*
		Settings.SoundPlaybackRate = mMenuOptions.soundRate;
		Settings.Stereo = mMenuOptions.stereo ? TRUE : FALSE;
		*/
		Settings.SixteenBitSound=true;

		sal_AudioInit(mMenuOptions.soundRate, 16,
					mMenuOptions.stereo, Memory.ROMFramesPerSecond);

		S9xInitSound (mMenuOptions.soundRate,
					mMenuOptions.stereo, sal_AudioGetBufferSize());
		S9xSetPlaybackRate(mMenuOptions.soundRate);
		S9xSetSoundMute (FALSE);

	} else {
		S9xSetSoundMute (TRUE);
	}

  	while(!mEnterMenu) 
  	{
		for (i=0;i<10;i++)
		{
			aim=sal_TimerRead();
			if (done < aim)
			{
				done++;
				if (mMenuOptions.frameSkip == 0) //Auto
					IPPU.RenderThisFrame = (done >= aim);
				else if (IPPU.RenderThisFrame = (--skip <= 0))
					skip = mMenuOptions.frameSkip;

				//Run SNES for one glorious frame
				S9xMainLoop ();

				if (sound) {
					S9xMixSamples((uint8 *) sal_GetCurrentAudioBuffer(),
								sal_AudioGetSampleCount());
					sal_SubmitSamples();
				}
//				HandleQuickStateRequests();
			}
			if (done>=aim) break; // Up to date now
			if (mEnterMenu) break;
		}
		done=aim; // Make sure up to date
		HandleQuickStateRequests();
  	}

	if (sound)
		sal_AudioClose();

	mEnterMenu=0;
	return mEnterMenu;

}
コード例 #13
0
void S9xAlsaSoundDriver::samples_available()
{
    snd_pcm_sframes_t frames_written, frames;
    int bytes;

    frames = snd_pcm_avail(pcm);

    if (frames < 0)
    {
        frames = snd_pcm_recover(pcm, frames, 1);
        return;
    }

    if (Settings.DynamicRateControl)
    {
        S9xUpdateDynamicRate(snd_pcm_frames_to_bytes(pcm, frames),
                             output_buffer_size);
    }

    int snes_frames_available = S9xGetSampleCount() >> 1;

    if (Settings.DynamicRateControl && !Settings.SoundSync)
    {
        // Using rate control, we should always keep the emulator's sound buffers empty to
        // maintain an accurate measurement.
        if (frames < snes_frames_available)
        {
            S9xClearSamples();
            return;
        }
    }

    if (Settings.SoundSync && !Settings.TurboMode && !Settings.Mute)
    {
        snd_pcm_nonblock(pcm, 0);
        frames = snes_frames_available;
    }
    else
    {
        snd_pcm_nonblock(pcm, 1);
        frames = MIN(frames, snes_frames_available);
    }

    bytes = snd_pcm_frames_to_bytes(pcm, frames);
    if (bytes <= 0)
        return;

    if (sound_buffer_size < bytes || sound_buffer == NULL)
    {
        sound_buffer = (uint8 *)realloc(sound_buffer, bytes);
        sound_buffer_size = bytes;
    }

    S9xMixSamples(sound_buffer, frames * 2);

    frames_written = 0;

    while (frames_written < frames)
    {
        int result;

        result = snd_pcm_writei(pcm,
                                sound_buffer +
                                    snd_pcm_frames_to_bytes(pcm, frames_written),
                                frames - frames_written);

        if (result < 0)
        {
            result = snd_pcm_recover(pcm, result, 1);

            if (result < 0)
            {
                break;
            }
        }
        else
        {
            frames_written += result;
        }
    }
}