예제 #1
0
        private int hleAudiocodecInit(TPointer workArea, int codecType, int outputChannels)
        {
            AudiocodecInfo info = infos.Remove(workArea.Address);

            if (info != null)
            {
                info.release();
                info = null;
            }

            switch (codecType)
            {
            case PSP_CODEC_AT3:
            case PSP_CODEC_AT3PLUS:
            case PSP_CODEC_AAC:
            case PSP_CODEC_MP3:
                break;

            default:
                Console.WriteLine(string.Format("sceAudiocodecInit unimplemented codecType=0x{0:X}", codecType));
                return(-1);
            }
            info = new AudiocodecInfo(workArea.Address);
            info.outputChannels = outputChannels;
            info.initCodec(codecType);

            infos[workArea.Address] = info;

            workArea.setValue32(8, 0);             // error FieldInfo

            return(0);
        }
예제 #2
0
        public virtual int sceAudiocodecReleaseEDRAM(TPointer workArea)
        {
            if (edramInfo == null)
            {
                return(SceKernelErrors.ERROR_CODEC_AUDIO_EDRAM_NOT_ALLOCATED);
            }

            Modules.SysMemUserForUserModule.free(edramInfo);
            edramInfo = null;

            AudiocodecInfo info = infos.Remove(workArea.Address);

            if (info != null)
            {
                info.release();
                info.CodecInitialized = false;
            }

            return(0);
        }
예제 #3
0
        public virtual int sceAudiocodecDecode(TPointer workArea, int codecType)
        {
            workArea.setValue32(8, 0);             // err FieldInfo

            AudiocodecInfo info = infos[workArea.Address];

            if (info == null)
            {
                Console.WriteLine(string.Format("sceAudiocodecDecode no info available for workArea={0}", workArea));
                return(-1);
            }

            int inputBuffer  = workArea.getValue32(24);
            int outputBuffer = workArea.getValue32(32);
            int unknown1     = workArea.getValue32(40);
            int codingMode   = 0;
            int channels     = info.outputChannels;

            int inputBufferSize;

            switch (codecType)
            {
            case PSP_CODEC_AT3PLUS:
                if (workArea.getValue32(48) == 0)
                {
                    inputBufferSize = workArea.getValue32(64) + 2;
                }
                else
                {
                    inputBufferSize = 0x100A;
                }

                // Skip any audio frame header (found in PSMF files)
                Memory mem = workArea.Memory;
                if (mem.read8(inputBuffer) == 0x0F && mem.read8(inputBuffer + 1) == 0xD0)
                {
                    int frameHeader23    = (mem.read8(inputBuffer + 2) << 8) | mem.read8(inputBuffer + 3);
                    int audioFrameLength = (frameHeader23 & 0x3FF) << 3;
                    inputBufferSize = audioFrameLength;
                    inputBuffer    += 8;
                }
                break;

            case PSP_CODEC_AT3:
                switch (workArea.getValue32(40))
                {
                case 0x4:
                    inputBufferSize = 0x180;
                    break;

                case 0x6:
                    inputBufferSize = 0x130;
                    break;

                case 0xB:
                    inputBufferSize = 0xC0;
                    codingMode      = 1;
                    break;                                     // JOINT_STEREO
                    goto case 0xE;

                case 0xE:
                    inputBufferSize = 0xC0;
                    break;

                case 0xF:
                    inputBufferSize = 0x98;
                    channels        = 1;
                    break;                                     // MONO
                    goto default;

                default:
                    Console.WriteLine(string.Format("sceAudiocodecDecode Atrac3 unknown value 0x{0:X} at offset 40", workArea.getValue32(40)));
                    inputBufferSize = 0x180;
                    break;
                }
                break;

            case PSP_CODEC_MP3:
                inputBufferSize = workArea.getValue32(40);
                break;

            case PSP_CODEC_AAC:
                if (workArea.getValue8(44) == 0)
                {
                    inputBufferSize = 0x600;
                }
                else
                {
                    inputBufferSize = 0x609;
                }
                break;

            case 0x1004:
                inputBufferSize = workArea.getValue32(40);
                break;

            default:
                return(-1);
            }

            int outputBufferSize = getOutputBufferSize(workArea, codecType);

            workArea.setValue32(36, outputBufferSize);

            //if (log.DebugEnabled)
            {
                Console.WriteLine(string.Format("sceAudiocodecDecode inputBuffer=0x{0:X8}, outputBuffer=0x{1:X8}, inputBufferSize=0x{2:X}, outputBufferSize=0x{3:X}", inputBuffer, outputBuffer, inputBufferSize, outputBufferSize));
                Console.WriteLine(string.Format("sceAudiocodecDecode unknown1=0x{0:X8}", unknown1));
                if (log.TraceEnabled)
                {
                    log.trace(string.Format("sceAudiocodecDecode inputBuffer: {0}", Utilities.getMemoryDump(inputBuffer, inputBufferSize)));
                }
            }

            ICodec codec = info.Codec;

            if (!info.CodecInitialized)
            {
                codec.init(inputBufferSize, channels, info.outputChannels, codingMode);
                info.setCodecInitialized();
            }

            if (codec == null)
            {
                Console.WriteLine(string.Format("sceAudiocodecDecode no codec available for codecType=0x{0:X}", codecType));
                return(-1);
            }

            int bytesConsumed = codec.decode(inputBuffer, inputBufferSize, outputBuffer);

            //if (log.DebugEnabled)
            {
                if (bytesConsumed < 0)
                {
                    Console.WriteLine(string.Format("codec.decode returned error 0x{0:X8}, data: {1}", bytesConsumed, Utilities.getMemoryDump(inputBuffer, inputBufferSize)));
                }
                else
                {
                    Console.WriteLine(string.Format("sceAudiocodecDecode bytesConsumed=0x{0:X}", bytesConsumed));
                }
            }

            if (codec is Mp3Decoder)
            {
                Mp3Header mp3Header = ((Mp3Decoder)codec).Mp3Header;
                if (mp3Header != null)
                {
                    // See https://github.com/uofw/uofw/blob/master/src/avcodec/audiocodec.c
                    workArea.setValue32(68, mp3Header.bitrateIndex);                     // MP3 bitrateIndex [0..14]
                    workArea.setValue32(72, mp3Header.rawSampleRateIndex);               // MP3 freqType [0..3]

                    int type;
                    if (mp3Header.mpeg25 != 0)
                    {
                        type = 2;
                    }
                    else if (mp3Header.lsf != 0)
                    {
                        type = 0;
                    }
                    else
                    {
                        type = 1;
                    }
                    workArea.setValue32(56, type);                     // type [0..2]

                    //if (log.DebugEnabled)
                    {
                        Console.WriteLine(string.Format("sceAudiocodecDecode MP3 bitrateIndex={0:D}, rawSampleRateIndex={1:D}, type={2:D}", mp3Header.bitrateIndex, mp3Header.rawSampleRateIndex, type));
                    }
                }
            }

            workArea.setValue32(28, bytesConsumed > 0 ? bytesConsumed : inputBufferSize);

            Modules.ThreadManForUserModule.hleKernelDelayThread(sceMpeg.atracDecodeDelay, false);

            return(0);
        }