示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#3
0
        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);
        }