コード例 #1
0
ファイル: __sceAudio.cpp プロジェクト: HelicopterP/ppsspp
// numFrames is number of stereo frames.
// This is called from *outside* the emulator thread.
int __AudioMix(short *outstereo, int numFrames)
{
	// TODO: if mixFrequency != the actual output frequency, resample!
	lock_guard guard(section);
	int underrun = -1;
	s16 sampleL = 0;
	s16 sampleR = 0;
	bool anythingToPlay = false;
	for (int i = 0; i < numFrames; i++) {
		if (outAudioQueue.size() >= 2) {
			sampleL = outAudioQueue.pop_front();
			sampleR = outAudioQueue.pop_front();
			outstereo[i * 2 + 0] = sampleL;
			outstereo[i * 2 + 1] = sampleR;
			anythingToPlay = true;
		} else {
			if (underrun == -1) underrun = i;
			outstereo[i * 2 + 0] = sampleL;  // repeat last sample, can reduce clicking
			outstereo[i * 2 + 1] = sampleR;  // repeat last sample, can reduce clicking
		}
	}
	if (anythingToPlay && underrun >= 0) {
		DEBUG_LOG(HLE, "Audio out buffer UNDERRUN at %i of %i", underrun, numFrames);
	} else {
		// DEBUG_LOG(HLE, "No underrun, mixed %i samples fine", numFrames);
	}
	return underrun >= 0 ? underrun : numFrames;
}
コード例 #2
0
ファイル: __sceAudio.cpp プロジェクト: metalex10/ppsspp
void __AudioDoState(PointerWrap &p) {
	auto s = p.Section("sceAudio", 1);
	if (!s)
		return;

	p.Do(eventAudioUpdate);
	CoreTiming::RestoreRegisterEvent(eventAudioUpdate, "AudioUpdate", &hleAudioUpdate);
	p.Do(eventHostAudioUpdate);
	CoreTiming::RestoreRegisterEvent(eventHostAudioUpdate, "AudioUpdateHost", &hleHostAudioUpdate);

	p.Do(mixFrequency);

	if (s >= 2) {
		resampler.DoState(p);
	} else {
		// Only to preserve the previous file format. Might cause a slight audio glitch on upgrades?
		FixedSizeQueue<s16, 512 * 16> outAudioQueue;
		outAudioQueue.DoState(p);

		resampler.Clear();
	}

	int chanCount = ARRAY_SIZE(chans);
	p.Do(chanCount);
	if (chanCount != ARRAY_SIZE(chans))
	{
		ERROR_LOG(SCEAUDIO, "Savestate failure: different number of audio channels.");
		return;
	}
	for (int i = 0; i < chanCount; ++i)
		chans[i].DoState(p);

	__AudioCPUMHzChange();
}
コード例 #3
0
ファイル: __sceAudio.cpp プロジェクト: DJHartley/ppsspp
// Mix samples from the various audio channels into a single sample queue.
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
// just sleep the main emulator thread a little.
void __AudioUpdate()
{
	// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
	// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
	// if the buffer somehow gets full.

	s32 mixBuffer[hwBlockSize * 2];
	memset(mixBuffer, 0, sizeof(mixBuffer));

	for (int i = 0; i < PSP_AUDIO_CHANNEL_MAX; i++)
	{
		if (!chans[i].reserved)
			continue;
		if (!chans[i].sampleQueue.size()) {
			// ERROR_LOG(HLE, "No queued samples, skipping channel %i", i);
			continue;
		}

		for (int s = 0; s < hwBlockSize; s++)
		{
			if (chans[i].sampleQueue.size() >= 2)
			{
				s16 sampleL = chans[i].sampleQueue.pop_front();
				s16 sampleR = chans[i].sampleQueue.pop_front();
				mixBuffer[s * 2 + 0] += sampleL;
				mixBuffer[s * 2 + 1] += sampleR;
			} 
			else
			{
				ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, s, hwBlockSize);
				break;
			}
		}

		if (chans[i].sampleQueue.size() < chans[i].sampleCount * 2 * chanQueueMinSizeFactor)
		{
			// Ask the thread to send more samples until next time, queue is being drained.
			if (chans[i].waitingThread) {
				SceUID waitingThread = chans[i].waitingThread;
				chans[i].waitingThread = 0;
				// DEBUG_LOG(HLE, "Woke thread %i for some buffer filling", waitingThread);
				__KernelResumeThreadFromWait(waitingThread, chans[i].sampleCount);
			}
		}
	}

	if (g_Config.bEnableSound) {
		section.lock();
		if (outAudioQueue.room() >= hwBlockSize * 2) {
			// Push the mixed samples onto the output audio queue.
			for (int i = 0; i < hwBlockSize; i++) {
				s32 sampleL = mixBuffer[i * 2 + 0] >> 2;  // TODO - what factor?
				s32 sampleR = mixBuffer[i * 2 + 1] >> 2;

				outAudioQueue.push((s16)sampleL);
				outAudioQueue.push((s16)sampleR);
			}
		} else {
コード例 #4
0
ファイル: __sceAudio.cpp プロジェクト: xStars/ppsspp
// Mix samples from the various audio channels into a single sample queue.
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
// just sleep the main emulator thread a little.
void __AudioUpdate()
{
	// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
	// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
	// if the buffer somehow gets full.

	s32 mixBuffer[hwBlockSize * 2];
	memset(mixBuffer, 0, sizeof(mixBuffer));

	for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
	{
		if (!chans[i].reserved)
			continue;
		__AudioWakeThreads(chans[i], hwBlockSize);

		if (!chans[i].sampleQueue.size()) {
			// ERROR_LOG(HLE, "No queued samples, skipping channel %i", i);
			continue;
		}

		for (int s = 0; s < hwBlockSize; s++)
		{
			if (chans[i].sampleQueue.size() >= 2)
			{
				s16 sampleL = chans[i].sampleQueue.pop_front();
				s16 sampleR = chans[i].sampleQueue.pop_front();
				mixBuffer[s * 2 + 0] += sampleL;
				mixBuffer[s * 2 + 1] += sampleR;
			} 
			else
			{
				ERROR_LOG(HLE, "Channel %i buffer underrun at %i of %i", i, s, hwBlockSize);
				break;
			}
		}
	}

	if (g_Config.bEnableSound) {
		section.lock();
		if (outAudioQueue.room() >= hwBlockSize * 2) {
			// Push the mixed samples onto the output audio queue.
			for (int i = 0; i < hwBlockSize; i++) {
				s16 sampleL = clamp_s16(mixBuffer[i * 2 + 0]);
				s16 sampleR = clamp_s16(mixBuffer[i * 2 + 1]);

				outAudioQueue.push((s16)sampleL);
				outAudioQueue.push((s16)sampleR);
			}
		} else {
			// This happens quite a lot. There's still something slightly off
			// about the amount of audio we produce.
			DEBUG_LOG(HLE, "Audio outbuffer overrun! room = %i / %i", outAudioQueue.room(), (u32)outAudioQueue.capacity());
		}
		section.unlock();
	}
	
}
コード例 #5
0
ファイル: __sceAudio.cpp プロジェクト: Bulkman/ppsspp
// numFrames is number of stereo frames.
// This is called from *outside* the emulator thread.
int __AudioMix(short *outstereo, int numFrames)
{
	// TODO: if mixFrequency != the actual output frequency, resample!
	int underrun = -1;
	s16 sampleL = 0;
	s16 sampleR = 0;

	const s16 *buf1 = 0, *buf2 = 0;
	size_t sz1, sz2;
	{
		lock_guard guard(section);
		outAudioQueue.popPointers(numFrames * 2, &buf1, &sz1, &buf2, &sz2);
		memcpy(outstereo, buf1, sz1 * sizeof(s16));
		if (buf2) {
			memcpy(outstereo + sz1, buf2, sz2 * sizeof(s16));
		}
	}

	int remains = (int)(numFrames * 2 - sz1 - sz2);
	if (remains > 0)
		memset(outstereo + numFrames * 2 - remains, 0, remains);

	if (sz1 + sz2 < (size_t)numFrames) {
		underrun = (int)(sz1 + sz2) / 2;
		VERBOSE_LOG(SCEAUDIO, "Audio out buffer UNDERRUN at %i of %i", underrun, numFrames);
	}
	return underrun >= 0 ? underrun : numFrames;
}
コード例 #6
0
ファイル: __sceAudio.cpp プロジェクト: Bulkman/ppsspp
void __AudioDoState(PointerWrap &p) {
	p.Do(eventAudioUpdate);
	CoreTiming::RestoreRegisterEvent(eventAudioUpdate, "AudioUpdate", &hleAudioUpdate);
	p.Do(eventHostAudioUpdate);
	CoreTiming::RestoreRegisterEvent(eventHostAudioUpdate, "AudioUpdateHost", &hleHostAudioUpdate);

	p.Do(mixFrequency);

	{
		lock_guard guard(section);
		outAudioQueue.DoState(p);
	}

	int chanCount = ARRAY_SIZE(chans);
	p.Do(chanCount);
	if (chanCount != ARRAY_SIZE(chans))
	{
		ERROR_LOG(SCEAUDIO, "Savestate failure: different number of audio channels.");
		return;
	}
	for (int i = 0; i < chanCount; ++i)
		chans[i].DoState(p);

	p.DoMarker("sceAudio");
}
コード例 #7
0
int main(){
    FixedSizeQueue currentBuffer;
    int currentHigh;
    char dummyChar;
    std::ifstream dataFile;
    
    //open file
    dataFile.open("data/problem7Data.txt");
    if(dataFile.is_open()){
        //get first summation of 5 numbers
        for (int i=0; i<5; i++) {
            dataFile>>dummyChar;
            //convert char to integer value
            currentBuffer.insert((dummyChar - '0') % 48);
        }
        currentHigh=currentBuffer.product();
        
        /*continue adding 1 number, and checking summation against
        * current high until end of file*/
        while (!(dataFile.eof())) {
            dataFile>>dummyChar;
            currentBuffer.insert((dummyChar - '0') % 48);
            if ((currentBuffer.product()) > (currentHigh)) {
                currentHigh=currentBuffer.product();
            }
        }
        dataFile.close();
    }else{
コード例 #8
0
ファイル: __sceAudio.cpp プロジェクト: Bulkman/ppsspp
// Mix samples from the various audio channels into a single sample queue.
// This single sample queue is where __AudioMix should read from. If the sample queue is full, we should
// just sleep the main emulator thread a little.
void __AudioUpdate() {
	// Audio throttle doesn't really work on the PSP since the mixing intervals are so closely tied
	// to the CPU. Much better to throttle the frame rate on frame display and just throw away audio
	// if the buffer somehow gets full.
	bool firstChannel = true;

	for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)	{
		if (!chans[i].reserved)
			continue;

		__AudioWakeThreads(chans[i], 0, hwBlockSize);

		if (!chans[i].sampleQueue.size()) {
			continue;
		}

		if (hwBlockSize * 2 > chans[i].sampleQueue.size()) {
			ERROR_LOG(SCEAUDIO, "Channel %i buffer underrun at %i of %i", i, (int)chans[i].sampleQueue.size() / 2, hwBlockSize);
		}

		const s16 *buf1 = 0, *buf2 = 0;
		size_t sz1, sz2;

		chans[i].sampleQueue.popPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2);

		if (firstChannel) {
			for (size_t s = 0; s < sz1; s++)
				mixBuffer[s] = buf1[s];
			if (buf2) {
				for (size_t s = 0; s < sz2; s++)
					mixBuffer[s + sz1] = buf2[s];
			}
			firstChannel = false;
		} else {
			for (size_t s = 0; s < sz1; s++)
				mixBuffer[s] += buf1[s];
			if (buf2) {
				for (size_t s = 0; s < sz2; s++)
					mixBuffer[s + sz1] += buf2[s];
			}
		}
	}

	if (firstChannel) {
		memset(mixBuffer, 0, hwBlockSize * 2 * sizeof(s32));
	}

	if (g_Config.bEnableSound) {
		lock_guard guard(section);
		if (outAudioQueue.room() >= hwBlockSize * 2) {
			s16 *buf1 = 0, *buf2 = 0;
			size_t sz1, sz2;
			outAudioQueue.pushPointers(hwBlockSize * 2, &buf1, &sz1, &buf2, &sz2);
			for (size_t s = 0; s < sz1; s++)
				buf1[s] = clamp_s16(mixBuffer[s]);
			if (buf2) {
				for (size_t s = 0; s < sz2; s++)
					buf2[s] = clamp_s16(mixBuffer[s + sz1]);
			}
		} else {
			// This happens quite a lot. There's still something slightly off
			// about the amount of audio we produce.
		}
	}
}
コード例 #9
0
ファイル: __sceAudio.cpp プロジェクト: DJHartley/ppsspp
int eventAudioUpdate = -1;
int eventHostAudioUpdate = -1;
int mixFrequency = 44100;

const int hwSampleRate = 44100;
const int hwBlockSize = 64;
const int hostAttemptBlockSize = 256;
const int audioIntervalUs = (int)(1000000ULL * hwBlockSize / hwSampleRate);
const int audioHostIntervalUs = (int)(1000000ULL * hostAttemptBlockSize / hwSampleRate);

// High and low watermarks, basically.
const int chanQueueMaxSizeFactor = 4;
const int chanQueueMinSizeFactor = 1;

FixedSizeQueue<s16, hostAttemptBlockSize * 16> outAudioQueue;


void hleAudioUpdate(u64 userdata, int cyclesLate)
{
	__AudioUpdate();

	CoreTiming::ScheduleEvent(usToCycles(audioIntervalUs) - cyclesLate, eventAudioUpdate, 0);
}

void hleHostAudioUpdate(u64 userdata, int cyclesLate)
{
	host->UpdateSound();
	CoreTiming::ScheduleEvent(usToCycles(audioHostIntervalUs) - cyclesLate, eventHostAudioUpdate, 0);
}