public virtual int sceVaudioOutputBlocking(int vol, TPointer buf) { int result = 0; SoundChannel pspVaudioChannel = Modules.sceAudioModule.FreeSRCChannel; if (!pspVaudioChannel.OutputBlocking) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceVaudioOutputBlocking[not blocking] {0}", pspVaudioChannel)); } if ((vol & PSP_VAUDIO_VOLUME_BASE) != PSP_VAUDIO_VOLUME_BASE) { changeChannelVolume(pspVaudioChannel, vol, vol); } result = doAudioOutput(pspVaudioChannel, buf.Address); //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceVaudioOutputBlocking[not blocking] returning {0:D} ({1})", result, pspVaudioChannel)); } Modules.ThreadManForUserModule.hleRescheduleCurrentThread(); } else { //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceVaudioOutputBlocking[blocking] {0}", pspVaudioChannel)); } blockThreadOutput(pspVaudioChannel, buf.Address, vol, vol); } return(result); }
protected internal static void blockThreadOutput(SoundChannel channel, int addr, int leftVolume, int rightVolume) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; blockThreadOutput(threadMan.CurrentThreadID, channel, addr, leftVolume, rightVolume); threadMan.hleBlockCurrentThread(SceKernelThreadInfo.JPCSP_WAIT_AUDIO); channel.Busy = true; }
//public static Logger log = Modules.getLogger("sceVaudio"); public override void start() { SoundChannel.init(); // The PSP is using the same channel as the SRC channel(s) pspVaudio1Channel = Modules.sceAudioModule.pspSRC1Channel; pspVaudio2Channel = Modules.sceAudioModule.pspSRC2Channel; pspVaudioChannelReserved = false; base.start(); }
protected internal static void blockThreadOutput(int threadId, SoundChannel channel, int addr, int leftVolume, int rightVolume) { IAction action = new AudioBlockingOutputAction(threadId, channel, addr, leftVolume, rightVolume); int delayMicros = channel.getUnblockOutputDelayMicros(addr == 0); long schedule = Emulator.Clock.microTime() + delayMicros; //if (log.DebugEnabled) { Console.WriteLine(string.Format("blockThreadOutput micros={0:D}, schedule={1:D}", delayMicros, schedule)); } Emulator.Scheduler.addAction(schedule, action); }
protected internal static int doAudioOutput(SoundChannel channel, int pvoid_buf) { int ret = -1; if (channel.Reserved) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("doAudioOutput({0}, 0x{1:X8})", channel.ToString(), pvoid_buf)); } int bytesPerSample = channel.FormatStereo ? 4 : 2; int nbytes = bytesPerSample * channel.SampleLength; sbyte[] data = new sbyte[nbytes]; IMemoryReader memoryReader = MemoryReader.getMemoryReader(pvoid_buf, nbytes, 2); if (channel.FormatMono) { int volume = Audio.getVolume(channel.LeftVolume); for (int i = 0; i < nbytes; i += 2) { short sample = (short)memoryReader.readNext(); sample = SoundChannel.adjustSample(sample, volume); SoundChannel.storeSample(sample, data, i); } } else { int leftVolume = Audio.getVolume(channel.LeftVolume); int rightVolume = Audio.getVolume(channel.RightVolume); for (int i = 0; i < nbytes; i += 4) { short lsample = (short)memoryReader.readNext(); short rsample = (short)memoryReader.readNext(); lsample = SoundChannel.adjustSample(lsample, leftVolume); rsample = SoundChannel.adjustSample(rsample, rightVolume); SoundChannel.storeSample(lsample, data, i); SoundChannel.storeSample(rsample, data, i + 2); } } Modules.sceAudioModule.audioData = data; channel.play(data); ret = channel.SampleLength; } else { Console.WriteLine("doAudioOutput: channel " + channel.Index + " not reserved"); } return(ret); }
public override void start() { SoundChannel.init(); // The audio driver is capable of handling PCM and VAG (ADPCM) playback, // but it uses the same channels for this processing. // E.g.: Use channels 0 to 4 to playback 4 VAG files or use channels 0 to 2 // to playback raw PCM data. // Note: Currently, working with pspPCMChannels only is enough. pspPCMChannels = new SoundChannel[PSP_AUDIO_CHANNEL_MAX]; for (int channel = 0; channel < pspPCMChannels.Length; channel++) { pspPCMChannels[channel] = new SoundChannel(channel); } pspSRC1Channel = new SoundChannel(8); // Use a special channel 8 to handle SRC functions (first channel). pspSRC2Channel = new SoundChannel(9); // Use a special channel 9 to handle SRC functions (second channel). base.start(); }
protected internal static int changeChannelVolume(SoundChannel channel, int leftvol, int rightvol) { int ret = -1; if (channel.Reserved) { // Negative volume means no change if (leftvol >= 0) { channel.LeftVolume = leftvol; } if (rightvol >= 0) { channel.RightVolume = rightvol; } ret = 0; } return(ret); }
public virtual void hleAudioBlockingOutput(int threadId, SoundChannel channel, int addr, int leftVolume, int rightVolume) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleAudioBlockingOutput {0}", channel.ToString())); } if (addr == 0) { // If another thread is also sending audio data on this channel, // do not wait for the channel to be drained, unblock the thread now. ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo thread = threadMan.getThreadById(threadId); if (thread != null) { thread.cpuContext._v0 = channel.SampleLength; threadMan.hleUnblockThread(threadId); } channel.Busy = false; } else if (!channel.OutputBlocking) { ThreadManForUser threadMan = Modules.ThreadManForUserModule; SceKernelThreadInfo thread = threadMan.getThreadById(threadId); if (thread != null) { changeChannelVolume(channel, leftVolume, rightVolume); int ret = doAudioOutput(channel, addr); thread.cpuContext._v0 = ret; threadMan.hleUnblockThread(threadId); } channel.Busy = false; } else { blockThreadOutput(threadId, channel, addr, leftVolume, rightVolume); } }
protected internal virtual int hleAudioGetChannelRestLength(SoundChannel channel) { int len = channel.RestLength; // To avoid small "clicks" in the sound, simulate a rest Length of 0 // when approaching the end of the buffered samples. // 2048 is an empirical value. if (len > 0 && len <= 2048) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleAudioGetChannelRestLength truncating rest Length {0:D} to 0", len)); } len = 0; } //if (log.DebugEnabled) { Console.WriteLine(string.Format("hleAudioGetChannelRestLength({0:D}) = {1:D}", channel.Index, len)); } return(len); }
public virtual int sceAudioSRCOutputBlocking(int vol, TPointer buf) { // Tested on PSP: any sound volume above MAX_VOLUME has the same effect as MAX_VOLUME. int channelVolume = min(SoundChannel.MAX_VOLUME, vol); SoundChannel pspSRCChannel = FreeSRCChannel; if (pspSRCChannel == null) { return(SceKernelErrors.ERROR_AUDIO_CHANNEL_BUSY); } pspSRCChannel.Volume = channelVolume; if (buf.Null) { // Tested on PSP: // SRC audio also delays when buf == 0, in order to drain all // audio samples from the audio driver. if (!pspSRCChannel.Drained) { //if (log.DebugEnabled) { Console.WriteLine("sceAudioSRCOutputBlocking[buf==0] blocking " + pspSRCChannel); } // Do not update volume, it has already been updated above blockThreadOutput(pspSRCChannel, buf.Address, -1, -1); } else { Modules.ThreadManForUserModule.hleYieldCurrentThread(); } } else if (!pspSRC1Channel.Reserved) { // Channel is automatically reserved. The audio data (buf) is not used in this case. //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceAudioSRCOutputBlocking automatically reserving channel {0}", pspSRCChannel)); } pspSRC1Channel.Reserved = true; pspSRC2Channel.Reserved = true; } else { if (!pspSRCChannel.OutputBlocking) { //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceAudioSRCOutputBlocking[not blocking] {0} to {1}", buf, pspSRCChannel.ToString())); } Modules.ThreadManForUserModule.hleRescheduleCurrentThread(); return(doAudioOutput(pspSRCChannel, buf.Address)); } //if (log.DebugEnabled) { Console.WriteLine(string.Format("sceAudioSRCOutputBlocking[blocking] {0} to {1}", buf, pspSRCChannel.ToString())); } // Do not update volume, it has already been updated above blockThreadOutput(pspSRCChannel, buf.Address, -1, -1); } return(0); }
protected internal virtual int changeChannelVolume(SoundChannel channel, int leftvol, int rightvol) { return(sceAudio.changeChannelVolume(channel, leftvol, rightvol)); }
protected internal virtual void blockThreadOutput(SoundChannel channel, int addr, int leftVolume, int rightVolume) { sceAudio.blockThreadOutput(channel, addr, leftVolume, rightVolume); }
protected internal virtual int doAudioOutput(SoundChannel channel, int pvoid_buf) { return(sceAudio.doAudioOutput(channel, pvoid_buf)); }