Esempio n. 1
0
 public void Write(object value)
 {
     if (stream == null)
     {
         throw new InvalidOperationException("Cannot write to a closed TcpSession object.");
     }
     try
     {
         Marshaler.Marshal(stream, connection.charsetMap, value);
     }
     catch
     {
         broken = true;
         throw;
     }
     written = true;
 }
Esempio n. 2
0
        private unsafe AssetBuffer ProcessAudioFileInstance(InstanceDeclaration declaration)
        {
            AssetBuffer       result      = new AssetBuffer();
            bool              isBigEndian = _platform != TargetPlatform.Win32;
            Node              node        = new Node(declaration.Node.CreateNavigator(), declaration.Document.NamespaceManager);
            AudioFileRuntime *audioFileRuntime;

            using (Tracker tracker = new Tracker((void **)&audioFileRuntime, (uint)sizeof(AudioFileRuntime), isBigEndian))
            {
                AudioFile audioFile = new AudioFile();
                audioFile.Marshal(node);
                string file    = declaration.XmlNode.Attributes["File"].Value;
                bool   isSound = Path.GetDirectoryName(file).ToLower().EndsWith("\\sounds");
                int    codec;
                PCAudioCompressionSetting compression = audioFile.PCCompression ?? (isSound ? PCAudioCompressionSetting.XAS : PCAudioCompressionSetting.NONE);
                switch (compression)
                {
                case PCAudioCompressionSetting.NONE:     // would become '1'
                    codec = 1;
                    break;

                case PCAudioCompressionSetting.XAS:     // would become '29', xbox XMA would be '28'
                    codec = 29;
                    break;

                case PCAudioCompressionSetting.EALAYER3:     // would become '31', '30' in TW (-ealayer3_int)
                    codec = 31;
                    break;

                default:
                    throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Internal error: xml compiler returned bad PC audio compression type of {0}", compression);
                }
                bool isStreamed = audioFile.IsStreamedOnPC ?? !isSound;
                if (audioFile.SubtitleStringName is null)
                {
                    audioFile.SubtitleStringName = $"DIALOGEVENT:{Path.GetFileNameWithoutExtension(file)}SubTitle";
                }
                Marshaler.Marshal(audioFile.SubtitleStringName, &audioFileRuntime->SubtitleStringName, tracker);
                int type = SIMEX_id(file, 0);
                if (type < 0)
                {
                    Console.WriteLine("Warning: Unable to identify format of \"{0}\"; cannot process. (Error: {1})", file, SIMEX_getlasterr());
                    return(null);
                }
                if (type != 1)
                {
                    Console.WriteLine("Warning: Input files must be WAVE format. Cannot process \"{0}\"", file);
                    return(null);
                }
                SINSTANCE *instance = null;
                int        count    = SIMEX_open(file, 0, type, &instance);
                using (AutoSINSTANCECloser closer = new AutoSINSTANCECloser(instance))
                {
                    if (count <= 0 || instance == null)
                    {
                        Console.WriteLine("Warning: Could not begin audio processing of \"{0}\": {1}.", file, SIMEX_getlasterr());
                        return(null);
                    }
                    string tempFile = declaration.CustomDataPath + _tempFilenameSuffix;
                    using (AutoCleanUpTempFiles tempFiles = new AutoCleanUpTempFiles(tempFile))
                    {
                        SINSTANCE *instance2 = null;
                        if (SIMEX_create(tempFile, 39, &instance2) == 0)
                        {
                            throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Internal error preparing audio output file \"{0}\" (SIMEX_create(): {1}).", tempFile, SIMEX_getlasterr());
                        }
                        using (AutoSINSTANCEWCloser closer2 = new AutoSINSTANCEWCloser(instance2))
                        {
                            for (int i = 0; i < count; i++)
                            {
                                SINFO *info = null;
                                if (SIMEX_info(instance, &info, i) == 0)
                                {
                                    throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Internal error reading element {0} of \"{1}\" (SIMEX_info(): {2}).", file, SIMEX_getlasterr());
                                }
                                using (AutoSINFOFreer freer = new AutoSINFOFreer(info))
                                {
                                    if (info != null)
                                    {
                                        if (SIMEX_read(instance, info, i) == 0)
                                        {
                                            throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Internal error reading element {0} of \"{1}\" (SIMEX_read(): {2}).", file, SIMEX_getlasterr());
                                        }
                                        if (isStreamed)
                                        {
                                            SIMEX_setplayloc(info, 4096);
                                            _tracer.TraceNote("Setting play location to streamed");
                                        }
                                        else
                                        {
                                            SIMEX_setplayloc(info, 2048);
                                            _tracer.TraceNote("Setting play location to RAM");
                                        }
                                        SIMEX_setcodec(info, codec);
                                        _tracer.TraceNote("Setting compression type to {0}. ", SIMEX_getsamplerepname(codec));
                                    }
                                    if (codec == 31 || codec == 38)
                                    {
                                        int quality = audioFile.PCQuality;
                                        if (quality < 0 || quality > 100)
                                        {
                                            throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Audio file {0}: Quality parameter must be between 0 and 100", file);
                                        }
                                        SIMEX_setvbrquality(info, quality);
                                        _tracer.TraceNote("Setting compression quality to {0}", quality);
                                    }
                                    if (audioFile.PCSampleRate.HasValue)
                                    {
                                        int oldrate = SIMEX_getsamplerate(info);
                                        int newrate = audioFile.PCSampleRate.Value;
                                        if (oldrate != newrate)
                                        {
                                            if (newrate < 400 || newrate > 96000)
                                            {
                                                throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Audio file {0}: Sample rate must be between 400 and 96000", file);
                                            }
                                            _tracer.TraceNote("Resampling from {0} to {1} ", oldrate, newrate);
                                            SIMEX_resample(info, newrate);
                                            int rate = SIMEX_getsamplerate(info);
                                            if (newrate != rate)
                                            {
                                                Console.WriteLine("Warning: Downsampling of audio file {0} not completely sucessful. Wanted final sample of {1}Hz but got {2}Hz", file, newrate, rate);
                                            }
                                        }
                                    }
                                    audioFileRuntime->NumberOfChannels = SIMEX_getchannelconfig(info);
                                    audioFileRuntime->NumberOfSamples  = SIMEX_getnumsamples(info);
                                    audioFileRuntime->SampleRate       = SIMEX_getsamplerate(info);
                                    if (audioFileRuntime->NumberOfChannels != 1 && audioFileRuntime->NumberOfChannels != 2 && audioFileRuntime->NumberOfChannels != 4 && audioFileRuntime->NumberOfChannels != 6)
                                    {
                                        Console.WriteLine("Warning: Audio file {0} has {1} channels. The only supported channel counts are 1, 2, 4, and 6; sample will probably use only the first channel in the engine", file, audioFileRuntime->NumberOfChannels);
                                    }
                                    if (SIMEX_write(instance2, info, i) == 0)
                                    {
                                        throw new BinaryAssetBuilderException(ErrorCode.InternalError, "Internal error writing element {0} of \"{1}\" (SIMEX_write(): {2}).", i, tempFile, SIMEX_getlasterr());
                                    }
                                }
                            }
                            string snr = tempFile + ".snr";
                            byte[] buffer;
                            using (Stream stream = File.Open(snr, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                buffer = new byte[stream.Length];
                                stream.Read(buffer, 0, buffer.Length);
                            }
                            if (isStreamed)
                            {
                                string sns = tempFile + ".sns";
                                if (File.Exists(declaration.CustomDataPath))
                                {
                                    File.Delete(declaration.CustomDataPath);
                                }
                                _tracer.TraceNote("Creating output file {0}\n", declaration.CustomDataPath);
                                File.Move(sns, declaration.CustomDataPath);
                                audioFileRuntime->HeaderDataSize = buffer.Length;
                                fixed(byte *pBuffer = &buffer[0])
                                {
                                    using (Tracker.Context context = tracker.Push(&audioFileRuntime->HeaderData, 1u, (uint)buffer.Length))
                                    {
                                        Native.MsVcRt.MemCpy(new IntPtr(audioFileRuntime->HeaderData), new IntPtr(pBuffer), new Native.SizeT(buffer.Length));
                                    }
                                }
                            }
                            else
                            {
                                if (File.Exists(declaration.CustomDataPath))
                                {
                                    File.Delete(declaration.CustomDataPath);
                                }
                                _tracer.TraceNote("Creating output file {0}\n", declaration.CustomDataPath);
                                File.Move(snr, declaration.CustomDataPath);
                            }
                            FinalizeTracker(tracker, result);
                        }
                    }
                }
            }
            return(result);
        }