Пример #1
0
        public AudioEngine(
            string settingsFile,
            TimeSpan lookAheadTime,
            string rendererId
            )
        {
            if (String.IsNullOrEmpty(settingsFile))
            {
                throw new ArgumentNullException("settingsFile");
            }

            // Read entire file into memory, pin buffer
            buffer = TitleContainer.ReadAllBytes(settingsFile);
            pin    = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            // Generate engine parameters
            FAudio.FACTRuntimeParameters settings = new FAudio.FACTRuntimeParameters();
            settings.pGlobalSettingsBuffer    = pin.AddrOfPinnedObject();
            settings.globalSettingsBufferSize = (uint)buffer.Length;
            xactNotificationFunc            = OnXACTNotification;
            settings.fnNotificationCallback = Marshal.GetFunctionPointerForDelegate(
                xactNotificationFunc
                );

            // Special parameters from constructor
            settings.lookAheadTime = (uint)lookAheadTime.Milliseconds;
            if (!string.IsNullOrEmpty(rendererId))
            {
                // FIXME: wchar_t? -flibit
                settings.pRendererID = Marshal.StringToHGlobalAuto(rendererId);
            }

            // Init engine, finally
            FAudio.FACTCreateEngine(0, out handle);
            if (FAudio.FACTAudioEngine_Initialize(handle, ref settings) != 0)
            {
                throw new InvalidOperationException(
                          "Engine initialization failed!"
                          );
            }

            // Free the settings strings
            if (settings.pRendererID != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(settings.pRendererID);
            }

            // Grab RendererDetails
            ushort rendererCount;

            FAudio.FACTAudioEngine_GetRendererCount(
                handle,
                out rendererCount
                );
            if (rendererCount == 0)
            {
                Dispose();
                throw new NoAudioHardwareException();
            }
            rendererDetails = new RendererDetail[rendererCount];
            char[] displayName = new char[0xFF];
            char[] rendererID  = new char[0xFF];
            for (ushort i = 0; i < rendererCount; i += 1)
            {
                FAudio.FACTRendererDetails details;
                FAudio.FACTAudioEngine_GetRendererDetails(
                    handle,
                    i,
                    out details
                    );
                unsafe
                {
                    for (int j = 0; j < 0xFF; j += 1)
                    {
                        displayName[j] = (char)details.displayName[j];
                        rendererID[j]  = (char)details.rendererID[j];
                    }
                }
                rendererDetails[i] = new RendererDetail(
                    new string(displayName),
                    new string(rendererID)
                    );
            }

            // Init 3D audio
            handle3D = new byte[FAudio.F3DAUDIO_HANDLE_BYTESIZE];
            FAudio.FACT3DInitialize(
                handle,
                handle3D
                );

            // Grab channel count for DSP_SETTINGS
            FAudio.FAudioWaveFormatExtensible mixFormat;
            FAudio.FACTAudioEngine_GetFinalMixFormat(
                handle,
                out mixFormat
                );
            channels = mixFormat.Format.nChannels;

            // All XACT references have to go through here...
            notificationDesc = new FAudio.FACTNotificationDescription();
        }
Пример #2
0
        public AudioEngine(
            string settingsFile,
            TimeSpan lookAheadTime,
            string rendererId
            )
        {
            if (String.IsNullOrEmpty(settingsFile))
            {
                throw new ArgumentNullException("settingsFile");
            }

            // Allocate (but don't initialize just yet!)
            FAudio.FACTCreateEngine(0, out handle);

            // Grab RendererDetails
            ushort rendererCount;

            FAudio.FACTAudioEngine_GetRendererCount(
                handle,
                out rendererCount
                );
            if (rendererCount == 0)
            {
                FAudio.FACTAudioEngine_Release(handle);
                throw new NoAudioHardwareException();
            }
            rendererDetails = new RendererDetail[rendererCount];
            byte[] converted = new byte[0xFF * sizeof(short)];
            for (ushort i = 0; i < rendererCount; i += 1)
            {
                FAudio.FACTRendererDetails details;
                FAudio.FACTAudioEngine_GetRendererDetails(
                    handle,
                    i,
                    out details
                    );
                unsafe
                {
                    Marshal.Copy((IntPtr)details.displayName, converted, 0, converted.Length);
                    string name = System.Text.Encoding.Unicode.GetString(converted).TrimEnd('\0');
                    Marshal.Copy((IntPtr)details.rendererID, converted, 0, converted.Length);
                    string id = System.Text.Encoding.Unicode.GetString(converted).TrimEnd('\0');
                    rendererDetails[i] = new RendererDetail(name, id);
                }
            }

            // Read entire file into memory, let FACT manage the pointer
            IntPtr bufferLen;
            IntPtr buffer = TitleContainer.ReadToPointer(settingsFile, out bufferLen);

            // Generate engine parameters
            FAudio.FACTRuntimeParameters settings = new FAudio.FACTRuntimeParameters();
            settings.pGlobalSettingsBuffer    = buffer;
            settings.globalSettingsBufferSize = (uint)bufferLen;
            settings.globalSettingsFlags      = FAudio.FACT_FLAG_MANAGEDATA;
            xactNotificationFunc            = OnXACTNotification;
            settings.fnNotificationCallback = Marshal.GetFunctionPointerForDelegate(
                xactNotificationFunc
                );

            // Special parameters from constructor
            settings.lookAheadTime = (uint)lookAheadTime.Milliseconds;
            if (!string.IsNullOrEmpty(rendererId))
            {
                // FIXME: wchar_t? -flibit
                settings.pRendererID = Marshal.StringToHGlobalAuto(rendererId);
            }

            // Init engine, finally
            if (FAudio.FACTAudioEngine_Initialize(handle, ref settings) != 0)
            {
                throw new InvalidOperationException(
                          "Engine initialization failed!"
                          );
            }

            // Free the settings strings
            if (settings.pRendererID != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(settings.pRendererID);
            }

            // Init 3D audio
            handle3D = new byte[FAudio.F3DAUDIO_HANDLE_BYTESIZE];
            FAudio.FACT3DInitialize(
                handle,
                handle3D
                );

            // Grab channel count for DSP_SETTINGS
            FAudio.FAudioWaveFormatExtensible mixFormat;
            FAudio.FACTAudioEngine_GetFinalMixFormat(
                handle,
                out mixFormat
                );
            channels = mixFormat.Format.nChannels;

            // All XACT references have to go through here...
            notificationDesc       = new FAudio.FACTNotificationDescription();
            notificationDesc.flags = FAudio.FACT_FLAG_NOTIFICATION_PERSIST;
            notificationDesc.type  = FAudio.FACTNOTIFICATIONTYPE_WAVEBANKDESTROYED;
            FAudio.FACTAudioEngine_RegisterNotification(
                handle,
                ref notificationDesc
                );
            notificationDesc.type = FAudio.FACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED;
            FAudio.FACTAudioEngine_RegisterNotification(
                handle,
                ref notificationDesc
                );
            notificationDesc.type = FAudio.FACTNOTIFICATIONTYPE_CUEDESTROYED;
            FAudio.FACTAudioEngine_RegisterNotification(
                handle,
                ref notificationDesc
                );
        }