Ejemplo n.º 1
0
        void SetupAUGraph()
        {
            graph = new AUGraph();

            AudioComponentDescription mixerDescription = new AudioComponentDescription();

            mixerDescription.ComponentType         = AudioComponentType.Mixer;
            mixerDescription.ComponentSubType      = (int)AudioTypeMixer.MultiChannel;
            mixerDescription.ComponentFlags        = 0;
            mixerDescription.ComponentFlagsMask    = 0;
            mixerDescription.ComponentManufacturer = AudioComponentManufacturerType.Apple;

            AudioComponentDescription outputDesciption = new AudioComponentDescription();

            outputDesciption.ComponentType         = AudioComponentType.Output;
            outputDesciption.ComponentSubType      = (int)AudioTypeOutput.System;
            outputDesciption.ComponentFlags        = 0;
            outputDesciption.ComponentFlagsMask    = 0;
            outputDesciption.ComponentManufacturer = AudioComponentManufacturerType.Apple;

            int mixerNode  = graph.AddNode(mixerDescription);
            int outputNode = graph.AddNode(outputDesciption);

            AUGraphError error = graph.ConnnectNodeInput(mixerNode, 0, outputNode, 0);

            Assert.AreEqual(AUGraphError.OK, error);

            graph.Open();

            mMixer = graph.GetNodeInfo(mixerNode);

            AudioUnitStatus status = mMixer.SetElementCount(AudioUnitScopeType.Input, 0);

            Assert.AreEqual(AudioUnitStatus.OK, status);
        }
Ejemplo n.º 2
0
		bool createAUGraph ()
		{
			AUGraphError result = 0;
			int samplerNode, ioNode;

			var cd = new AudioComponentDescription () {
				ComponentManufacturer = AudioComponentManufacturerType.Apple,
				ComponentFlags = 0,
				ComponentFlagsMask = 0
			};

			processingGraph = new AUGraph ();

			cd.ComponentType = AudioComponentType.MusicDevice;
			cd.ComponentSubType = (int)AudioTypeMusicDevice.Sampler; //0x73616d70;

			samplerNode = processingGraph.AddNode (cd);

			cd.ComponentType = AudioComponentType.Output;
			cd.ComponentSubType = (int)AudioTypeOutput.Remote; //0x72696f63;

			ioNode = processingGraph.AddNode (cd);

			processingGraph.Open ();

			result = processingGraph.ConnnectNodeInput (samplerNode, 0, ioNode, 0);
			if (result != AUGraphError.OK)
				throw new Exception ("Unable to open the audio processing graph.  Error code: " + result);
			samplerUnit = processingGraph.GetNodeInfo (samplerNode);
			ioUnit = processingGraph.GetNodeInfo (ioNode);

			return true;
		}
Ejemplo n.º 3
0
		bool CreateAUGraph ()
		{
			processingGraph = new AUGraph ();

			int samplerNode, ioNode;

			var musicSampler = new AudioComponentDescription () {
				ComponentManufacturer = AudioComponentManufacturerType.Apple,
				ComponentType = AudioComponentType.MusicDevice,
				ComponentSubType = (int)AudioTypeMusicDevice.Sampler
			};
			samplerNode = processingGraph.AddNode (musicSampler);

			var remoteOutput = new AudioComponentDescription () {
				ComponentManufacturer = AudioComponentManufacturerType.Apple,
				ComponentType = AudioComponentType.Output,
				ComponentSubType = (int)AudioTypeOutput.Remote
			};
			ioNode = processingGraph.AddNode (remoteOutput);

			processingGraph.Open ();

			processingGraph.ConnnectNodeInput (
				sourceNode: samplerNode,
				sourceOutputNumber: 0,
				destNode: ioNode,
				destInputNumber: 0);

			samplerUnit = processingGraph.GetNodeInfo (samplerNode);


			return true;
		}
Ejemplo n.º 4
0
        public void GetCurrentDevice_Test()
        {
            theUnit unit = GetAudioUnitForTest();

            uint device = unit.GetCurrentDevice(AudioUnitScopeType.Global);

            Assert.IsTrue(device != 0);
        }
        unsafe void TapPrepare(MTAudioProcessingTap tap, nint maxFrames, ref AudioStreamBasicDescription processingFormat)
        {
            // Store sample rate for CenterFrequency property
            context.SampleRate = processingFormat.SampleRate;

            /* Verify processing format (this is not needed for Audio Unit, but for RMS calculation). */
            VerifyProcessingFormat(processingFormat);

            if (processingFormat.FormatFlags.HasFlag(AudioFormatFlags.IsNonInterleaved))
            {
                context.IsNonInterleaved = true;
            }

            /* Create bandpass filter Audio Unit */

            var audioComponentDescription = AudioComponentDescription.CreateEffect(AudioTypeEffect.BandPassFilter);
            // TODO: https://trello.com/c/GZUGUyH0
            var audioComponent = AudioComponent.FindNextComponent(null, ref audioComponentDescription);

            if (audioComponent == null)
            {
                return;
            }

            AudioUnitStatus error = AudioUnitStatus.NoError;

            AudioUnit.AudioUnit audioUnit = audioComponent.CreateAudioUnit();
            try {
                audioUnit.SetAudioFormat(processingFormat, AudioUnitScopeType.Input);
                audioUnit.SetAudioFormat(processingFormat, AudioUnitScopeType.Output);
            } catch (AudioUnitException) {
                error = AudioUnitStatus.FormatNotSupported;
            }

            if (error == AudioUnitStatus.NoError)
            {
                error = audioUnit.SetRenderCallback(Render, AudioUnitScopeType.Input);
            }

            if (error == AudioUnitStatus.NoError)
            {
                error = audioUnit.SetMaximumFramesPerSlice((uint)maxFrames, AudioUnitScopeType.Global);
            }

            if (error == AudioUnitStatus.NoError)
            {
                error = (AudioUnitStatus)audioUnit.Initialize();
            }

            if (error != AudioUnitStatus.NoError)
            {
                audioUnit.Dispose();
                audioUnit = null;
            }

            context.AudioUnit = audioUnit;
        }
Ejemplo n.º 6
0
        public void GetCurrentDevice_Test()
        {
            TestRuntime.AssertNotVirtualMachine();

            theUnit unit = GetAudioUnitForTest();

            uint device = unit.GetCurrentDevice(AudioUnitScopeType.Global);

            Assert.IsTrue(device != 0);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Builds the audio graph, initializes the mixer.
        /// </summary>
        protected void BuildAUGraph()
        {
            Graph = new AUGraph();

            // use splitter sub-type to create file writer tap

            // output unit. output to default audio device
            int outputNode = Graph.AddNode(AudioComponentDescription.CreateOutput(AudioTypeOutput.Default));

            // mixer unit
            //int mixerNode = Graph.AddNode(AudioComponentDescription.CreateMixer(AudioTypeMixer.MultiChannel));

            //var mixerDesc = AudioComponentDescription.CreateMixer(AudioTypeMixer.MultiChannel);
            MixerNode = AudioComponent.FindComponent(AudioTypeMixer.MultiChannel).CreateAudioUnit();

            // connect the mixer's output to the output's input
            //if (Graph.ConnnectNodeInput(mixerNode, 0, outputNode, 0) != AUGraphError.OK)
            //{
            //    throw new ApplicationException();
            //}

            // open the graph
            if (Graph.TryOpen() != 0)
            {
                throw new ApplicationException();
            }

            Graph.SetNodeInputCallback(outputNode, 0, OutputRenderDelegate);

            Output = Graph.GetNodeInfo(outputNode);
            //MixerNode = Graph.GetNodeInfo(mixerNode);
            // must set ouput volume because it defaults to 0
            MixerNode.SetParameter(AudioUnitParameterType.MultiChannelMixerVolume, 1, AudioUnitScopeType.Output, 0);
            //MixerNode.SetMaximumFramesPerSlice(4096, AudioUnitScopeType.Global);

            ConfigureMixerInputs();

            AudioStreamBasicDescription desc;

            // set output stream format
            desc            = MixerNode.GetAudioFormat(AudioUnitScopeType.Output);
            desc.SampleRate = Metronome.SampleRate;
            if (MixerNode.SetFormat(desc, AudioUnitScopeType.Output) != AudioUnitStatus.OK)
            {
                throw new ApplicationException();
            }

            // now that we;ve set everything up we can initialize the graph, this will aslo validate the connections
            if (Graph.Initialize() != AUGraphError.OK)
            {
                throw new ApplicationException();
            }

            MixerNode.Initialize();
        }
Ejemplo n.º 8
0
        public void AVAudioIONodeTests_AudioUnitTest()
        {
            Asserts.EnsureYosemite();

            AVAudioEngine eng  = new AVAudioEngine();
            AVAudioIONode node = eng.OutputNode;
            AUUnit        unit = node.AudioUnit;

            unit.GetElementCount(AudioUnitScopeType.Global);
            // Make sure this doens't crash.
        }
        void prepareAudioUnit()
        {
            // Updated for deprecated AudioSession
            var     session = AVAudioSession.SharedInstance();
            NSError error;

            if (session == null)
            {
                var alert = new UIAlertView("Session error", "Unable to create audio session", null, "Cancel");
                alert.Show();
                alert.Clicked += delegate
                {
                    alert.DismissWithClickedButtonIndex(0, true);
                    return;
                };
            }
            session.SetActive(true);
            session.SetCategory(AVAudioSessionCategory.PlayAndRecord);
            session.SetPreferredIOBufferDuration(0.005, out error);

            // Getting AudioComponent Remote output
            _audioComponent = AudioComponent.FindComponent(AudioTypeOutput.Remote);

            // creating an audio unit instance
            _audioUnit = new AudioUnit.AudioUnit(_audioComponent);

            // turning on microphone
            _audioUnit.SetEnableIO(true,
                                   AudioUnitScopeType.Input,
                                   1 // Remote Input
                                   );

            // setting audio format
            _audioUnit.SetAudioFormat(_dstFormat,
                                      AudioUnitScopeType.Input,
                                      0 // Remote Output
                                      );

            var format = AudioStreamBasicDescription.CreateLinearPCM(_sampleRate, bitsPerChannel: 32);

            format.FormatFlags = AudioStreamBasicDescription.AudioFormatFlagsNativeFloat;
            _audioUnit.SetAudioFormat(format, AudioUnitScopeType.Output, 1);

            // setting callback method
            _audioUnit.SetRenderCallback(_audioUnit_RenderCallback, AudioUnitScopeType.Global);

            _audioUnit.Initialize();
            _audioUnit.Start();
        }
Ejemplo n.º 10
0
        public Instrument(InstrumentInfo info, int channel, AUGraph graph, int ioNode)
        {
            Info = info;

            var samplerNode = graph.AddNode(AudioComponentDescription.CreateMusicDevice(AudioTypeMusicDevice.Sampler));

            graph.ConnnectNodeInput(samplerNode, 0, ioNode, (uint)channel);

            samplerUnit = graph.GetNodeInfo(samplerNode);
            samplerUnit.SetMaximumFramesPerSlice(4096, AudioUnitScopeType.Global, 0);

            this.channel = channel;

            LoadInstrument(info);
        }
Ejemplo n.º 11
0
        void createAudioProcessGraph()
        {
            graph = new AUGraph();

            var sampler = graph.AddNode(AudioComponentDescription.CreateMusicDevice(AudioTypeMusicDevice.Sampler));
            var inout   = graph.AddNode(AudioComponentDescription.CreateOutput(AudioTypeOutput.Remote));

            graph.Open();
            graph.ConnnectNodeInput(sampler, 0, inout, 0);

            samplerUnit = graph.GetNodeInfo(sampler);

            graph.Initialize();
            graph.Start();
        }
Ejemplo n.º 12
0
        theUnit GetAudioUnitForTest()
        {
            AudioComponentDescription desc = new AudioComponentDescription();

            desc.ComponentType         = AudioComponentType.Output;
            desc.ComponentSubType      = 1634230636;        // 'ahal'
            desc.ComponentFlags        = 0;
            desc.ComponentFlagsMask    = 0;
            desc.ComponentManufacturer = AudioComponentManufacturerType.Apple;

            AudioComponent comp = AudioComponent.FindNextComponent(null, ref desc);
            theUnit        unit = new theUnit(comp);

            return(unit);
        }
Ejemplo n.º 13
0
        public void AVAudioIONodeTests_AudioUnitTest()
        {
            TestRuntime.AssertNotVirtualMachine();

            Asserts.EnsureYosemite();

            using (AVAudioEngine eng = new AVAudioEngine()) {
                using (AVAudioIONode node = eng.OutputNode) {
                    using (AUUnit unit = node.AudioUnit)
                        unit.GetElementCount(AudioUnitScopeType.Global);
                    using (AUUnit unit = node.AudioUnit)
                        unit.GetElementCount(AudioUnitScopeType.Global);
                    using (AUUnit unit = node.AudioUnit)
                        unit.GetElementCount(AudioUnitScopeType.Global);
                }
            }
            // Make sure this doens't crash.
        }
        void PrepareAudioUnit()
        {
            // All iPhones and iPads have microphones, but early iPod touches did not
            if (!AudioSession.AudioInputAvailable)
            {
                var noInputAlert = new UIAlertView("No audio input", "No audio input device is currently attached", null, "Ok");
                noInputAlert.Show();
                return;
            }

            // Getting AudioComponent Remote output
            audioComponent = AudioComponent.FindComponent(AudioTypeOutput.Remote);
            CheckValue(audioComponent);

            // creating an audio unit instance
            audioUnit = new AudioUnit.AudioUnit(audioComponent);

            AudioUnitStatus status;

            status = audioUnit.SetEnableIO(true, AudioUnitScopeType.Input, 1);
            CheckStatus(status);
            status = audioUnit.SetEnableIO(true, AudioUnitScopeType.Output, 0);
            CheckStatus(status);

            dstFormat = new AudioStreamBasicDescription {
                SampleRate       = AudioSession.CurrentHardwareSampleRate,
                Format           = AudioFormatType.LinearPCM,
                FormatFlags      = AudioFormatFlags.IsSignedInteger | AudioFormatFlags.IsNonInterleaved,
                BytesPerPacket   = 4,
                FramesPerPacket  = 1,
                BytesPerFrame    = 4,
                ChannelsPerFrame = 2,
                BitsPerChannel   = 16
            };

            audioUnit.SetAudioFormat(dstFormat, AudioUnitScopeType.Input, 0);
            audioUnit.SetAudioFormat(dstFormat, AudioUnitScopeType.Output, 1);

            status = audioUnit.SetRenderCallback(RenderCallback, AudioUnitScopeType.Input, 0);
            CheckStatus(status);
        }
Ejemplo n.º 15
0
        void CreateAudioUnit()
        {
            if (_audioUnit != null)
            {
                _audioUnit.Dispose();
                _audioUnit = null;
            }

            ResetFormat(2);

            var audioUnit = new AudioUnit.AudioUnit(AudioComponent.FindComponent(AudioTypeOutput.Remote));

            if (_numInputChannels > 0)
            {
                audioUnit.SetEnableIO(true, AudioUnitScopeType.Input, 1);
            }

            audioUnit.SetRenderCallback(AudioUnit_RenderCallback, AudioUnitScopeType.Input);

            AudioUnitStatus status;

            status = audioUnit.SetFormat(_format, AudioUnitScopeType.Input, 0);
            if (status != AudioUnitStatus.OK)
            {
                throw new Exception("Could not initialize audio unit: " + status);
            }
            status = audioUnit.SetFormat(_format, AudioUnitScopeType.Output, 1);
            if (status != AudioUnitStatus.OK)
            {
                throw new Exception("Could not initialize audio unit: " + status);
            }

            var osStatus = audioUnit.Initialize();

            if (osStatus != 0)
            {
                throw new Exception("Could not initialize audio unit: " + osStatus);
            }

            _audioUnit = audioUnit;
        }
Ejemplo n.º 16
0
        public void Close()
        {
            if (_isRunning)
            {
                _isRunning = false;

                AudioSession.Category = AudioSessionCategory.MediaPlayback;
                AudioSession.SetActive(false);

                if (_audioUnit != null)
                {
                    _audioUnit.Dispose();
                    _audioUnit = null;
                }

                if (_out != null)
                {
                    _out.Close();
                }
            }
        }
Ejemplo n.º 17
0
        bool CreateAUGraph()
        {
            processingGraph = new AUGraph();

            int samplerNode, ioNode;

            var musicSampler = new AudioComponentDescription()
            {
                ComponentManufacturer = AudioComponentManufacturerType.Apple,
                ComponentType         = AudioComponentType.MusicDevice,
                ComponentSubType      = (int)AudioTypeMusicDevice.Sampler
            };

            samplerNode = processingGraph.AddNode(musicSampler);

            var remoteOutput = new AudioComponentDescription()
            {
                ComponentManufacturer = AudioComponentManufacturerType.Apple,
                ComponentType         = AudioComponentType.Output,
                ComponentSubType      = (int)AudioTypeOutput.Remote
            };

            ioNode = processingGraph.AddNode(remoteOutput);

            processingGraph.Open();

            processingGraph.ConnnectNodeInput(
                sourceNode: samplerNode,
                sourceOutputNumber: 0,
                destNode: ioNode,
                destInputNumber: 0);

            samplerUnit = processingGraph.GetNodeInfo(samplerNode);

            ioUnit = processingGraph.GetNodeInfo(ioNode);

            return(true);
        }
Ejemplo n.º 18
0
        bool createAUGraph()
        {
            AUGraphError result = 0;
            int          samplerNode, ioNode;

            var cd = new AudioComponentDescription()
            {
                ComponentManufacturer = AudioComponentManufacturerType.Apple,
                ComponentFlags        = 0,
                ComponentFlagsMask    = 0
            };

            processingGraph = new AUGraph();

            cd.ComponentType    = AudioComponentType.MusicDevice;
            cd.ComponentSubType = (int)AudioTypeMusicDevice.Sampler;             //0x73616d70;

            samplerNode = processingGraph.AddNode(cd);

            cd.ComponentType    = AudioComponentType.Output;
            cd.ComponentSubType = (int)AudioTypeOutput.Remote;             //0x72696f63;

            ioNode = processingGraph.AddNode(cd);

            processingGraph.Open();

            result = processingGraph.ConnnectNodeInput(samplerNode, 0, ioNode, 0);
            if (result != AUGraphError.OK)
            {
                throw new Exception("Unable to open the audio processing graph.  Error code: " + result);
            }
            samplerUnit = processingGraph.GetNodeInfo(samplerNode);
            ioUnit      = processingGraph.GetNodeInfo(ioNode);

            return(true);
        }
Ejemplo n.º 19
0
        public void InitAudio()
        {
            var     session = AVAudioSession.SharedInstance();
            NSError error;

            if (session == null)
            {
                var alert = new UIAlertView("Session error", "Unable to create audio session", null, "Cancel");
                alert.Show();
                alert.Clicked += delegate
                {
                    alert.DismissWithClickedButtonIndex(0, true);
                    return;
                };
            }
            session.SetActive(false);
            session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.AllowBluetooth | AVAudioSessionCategoryOptions.DefaultToSpeaker | AVAudioSessionCategoryOptions.DuckOthers);            //Neded so we can listen to remote events

            notification = AVAudioSession.Notifications.ObserveInterruption((sender, args) => {
                /* Handling audio interuption here */

                if (args.InterruptionType == AVAudioSessionInterruptionType.Began)
                {
                    if (_audioUnit != null && _audioUnit.IsPlaying)
                    {
                        _audioUnit.Stop();
                    }
                }

                System.Diagnostics.Debug.WriteLine("Notification: {0}", args.Notification);

                System.Diagnostics.Debug.WriteLine("InterruptionType: {0}", args.InterruptionType);
                System.Diagnostics.Debug.WriteLine("Option: {0}", args.Option);
            });

            var opts = session.CategoryOptions;

            session.SetPreferredIOBufferDuration(0.01, out error);

            session.SetActive(true);

            _audioFormat = AudioStreamBasicDescription.CreateLinearPCM(_sampleRate, bitsPerChannel: 32);

            _audioFormat.FormatFlags |= AudioFormatFlags.IsNonInterleaved | AudioFormatFlags.IsFloat;

            _audioComponent = AudioComponent.FindComponent(AudioTypeOutput.Remote);

            // creating an audio unit instance
            _audioUnit = new AudioUnit.AudioUnit(_audioComponent);



            // setting audio format
            _audioUnit.SetAudioFormat(_audioFormat,
                                      AudioUnitScopeType.Input,
                                      0 // Remote Output
                                      );

            //_audioFormat.FormatFlags = AudioStreamBasicDescription.AudioFormatFlagsNativeFloat;

            _audioUnit.SetAudioFormat(_audioFormat, AudioUnitScopeType.Output, 1);
            // setting callback method
            _audioUnit.SetRenderCallback(_audioUnit_RenderCallback, AudioUnitScopeType.Global);

            _audioUnit.Initialize();
            _audioUnit.Stop();
        }
        void StreamPropertyListenerProc(object sender, PropertyFoundEventArgs args)
        {
            if (args.Property == AudioFileStreamProperty.DataFormat)
            {
                dataFormat = audioFileStream.DataFormat;
                return;
            }

            if (args.Property != AudioFileStreamProperty.ReadyToProducePackets)
            {
                return;
            }

            if (audioQueue != null)
            {
                // TODO: Dispose
                throw new NotImplementedException();
            }

            audioQueue = new OutputAudioQueue(dataFormat);
            audioQueue.BufferCompleted += HandleBufferCompleted;

            AudioQueueStatus status;

            aqTap = audioQueue.CreateProcessingTap(TapProc, AudioQueueProcessingTapFlags.PreEffects, out status);
            if (status != AudioQueueStatus.Ok)
            {
                throw new ApplicationException("Could not create AQ tap");
            }

            // create an augraph to process in the tap. needs to convert from tapFormat to effect format and back

            /* note: this is invalidname's recipe to do an in-place effect when a format conversion is needed
             * before and after the effect, usually because effects want floats, and everything else in iOS
             * core audio works with ints (or, in rare cases, fixed-point).
             * the graph looks like this:
             * [render-callback] -> [converter] -> [effect] -> [converter] -> [generic-output]
             * prior to calling AudioUnitRender() on generic-output the ioData to a pointer that render-callback
             * knows about, and NULLs the ioData provided to AudioUnitRender(). the NULL tells generic-output to
             * pull from its upstream units (ie, the augraph), and copying off the ioData pointer allows the
             * render-callback	to provide it to the front of the stream. in some locales, this kind of shell game
             * is described as "batshit crazy", but it seems to work pretty well in practice.
             */

            auGraph = new AUGraph();
            auGraph.Open();
            var effectNode = auGraph.AddNode(AudioComponentDescription.CreateConverter(AudioTypeConverter.NewTimePitch));

            effectUnit = auGraph.GetNodeInfo(effectNode);

            var convertToEffectNode = auGraph.AddNode(AudioComponentDescription.CreateConverter(AudioTypeConverter.AU));
            var convertToEffectUnit = auGraph.GetNodeInfo(convertToEffectNode);

            var convertFromEffectNode = auGraph.AddNode(AudioComponentDescription.CreateConverter(AudioTypeConverter.AU));
            var convertFromEffectUnit = auGraph.GetNodeInfo(convertFromEffectNode);

            var genericOutputNode = auGraph.AddNode(AudioComponentDescription.CreateOutput(AudioTypeOutput.Generic));

            genericOutputUnit = auGraph.GetNodeInfo(genericOutputNode);

            // set the format conversions throughout the graph
            var effectFormat = effectUnit.GetAudioFormat(AudioUnitScopeType.Output);
            var tapFormat    = aqTap.ProcessingFormat;

            convertToEffectUnit.SetAudioFormat(tapFormat, AudioUnitScopeType.Input);
            convertToEffectUnit.SetAudioFormat(effectFormat, AudioUnitScopeType.Output);

            convertFromEffectUnit.SetAudioFormat(effectFormat, AudioUnitScopeType.Input);
            convertFromEffectUnit.SetAudioFormat(tapFormat, AudioUnitScopeType.Output);

            genericOutputUnit.SetAudioFormat(tapFormat, AudioUnitScopeType.Input);
            genericOutputUnit.SetAudioFormat(tapFormat, AudioUnitScopeType.Output);

            // set maximum fames per slice higher (4096) so we don't get kAudioUnitErr_TooManyFramesToProcess
            const uint maxFramesPerSlice = 4096;

            if (convertToEffectUnit.SetMaximumFramesPerSlice(maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
            {
                throw new ApplicationException();
            }
            if (effectUnit.SetMaximumFramesPerSlice(maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
            {
                throw new ApplicationException();
            }
            if (convertFromEffectUnit.SetMaximumFramesPerSlice(maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
            {
                throw new ApplicationException();
            }
            if (genericOutputUnit.SetMaximumFramesPerSlice(maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
            {
                throw new ApplicationException();
            }

            // connect the nodes
            auGraph.ConnnectNodeInput(convertToEffectNode, 0, effectNode, 0);
            auGraph.ConnnectNodeInput(effectNode, 0, convertFromEffectNode, 0);
            auGraph.ConnnectNodeInput(convertFromEffectNode, 0, genericOutputNode, 0);

            // set up the callback into the first convert unit
            if (convertToEffectUnit.SetRenderCallback(ConvertInputRenderCallback, AudioUnitScopeType.Global) != AudioUnitStatus.NoError)
            {
                throw new ApplicationException();
            }

            var res = auGraph.Initialize();

            if (res != AUGraphError.OK)
            {
                throw new ApplicationException();
            }
        }
Ejemplo n.º 21
0
        public AudioVoice(AudioEngine engine, SoundEffectInstance effectInstance, WaveFormat desiredFormat)
        {
            if (engine == null)
            {
                throw new ArgumentNullException("engine");
            }
            if (desiredFormat == null)
            {
                throw new ArgumentNullException("desiredFormat");
            }

            audioEngine         = engine;
            soundEffectInstance = effectInstance;
            waveFormat          = desiredFormat;
            BusIndexMixer       = uint.MaxValue;

            if (desiredFormat.BitsPerSample != 16)
            {
                throw new AudioSystemInternalException("Invalid Audio Format. " + desiredFormat.BitsPerSample + " bits by sample is not supported.");
            }

            lock (StaticMembersLock)
            {
                if (nbOfInstances == 0)
                {
                    // Create the Audio Graph
                    audioGraph = new AUGraph();

                    // Open the graph (does not initialize it yet)
                    audioGraph.Open();

                    // Create the AudioComponentDescrition corresponding to the IO Remote output and MultiChannelMixer
                    var remoteInOutComponentDesc       = AudioComponentDescription.CreateOutput(AudioTypeOutput.Remote);
                    var mixerMultiChannelComponentDesc = AudioComponentDescription.CreateMixer(AudioTypeMixer.MultiChannel);
                    var mixer3DComponentDesc           = AudioComponentDescription.CreateMixer(AudioTypeMixer.Spacial);

                    // Add the Audio Unit nodes to the AudioGraph
                    var outputUnitNodeId   = audioGraph.AddNode(remoteInOutComponentDesc);
                    var idChannelMixerNode = audioGraph.AddNode(mixerMultiChannelComponentDesc);
                    var id3DMixerNode      = audioGraph.AddNode(mixer3DComponentDesc);

                    // Connect the nodes together
                    CheckGraphError(audioGraph.ConnnectNodeInput(idChannelMixerNode, 0, outputUnitNodeId, 0), "Connection of the graph node failed.");
                    CheckGraphError(audioGraph.ConnnectNodeInput(id3DMixerNode, 0, idChannelMixerNode, MaxNumberOfTracks), "Connection of the graph node failed.");

                    // Get the MixerUnit objects
                    unitChannelMixer = audioGraph.GetNodeInfo(idChannelMixerNode);
                    unit3DMixer      = audioGraph.GetNodeInfo(id3DMixerNode);

                    // Set the mixers' output formats (the stream format is propagated along the linked input during the graph initialization)
                    var desiredSampleRate = (engine.AudioSampleRate != 0) ? engine.AudioSampleRate : AudioUnitOutputSampleRate;
                    unit3DMixer.SetAudioFormat(CreateLinear16BitsPcm(2, desiredSampleRate), AudioUnitScopeType.Output);
                    unitChannelMixer.SetAudioFormat(CreateLinear16BitsPcm(2, desiredSampleRate), AudioUnitScopeType.Output);

                    // set the element count to the max number of possible tracks before initializing the audio graph
                    CheckUnitStatus(unitChannelMixer.SetElementCount(AudioUnitScopeType.Input, MaxNumberOfTracks + 1), string.Format("Failed to set element count on ChannelMixer [{0}]", MaxNumberOfTracks + 1)); // +1 for the 3DMixer output
                    CheckUnitStatus(unit3DMixer.SetElementCount(AudioUnitScopeType.Input, MaxNumberOfTracks), string.Format("Failed to set element count on 3DMixer [{0}]", MaxNumberOfTracks));

                    // set a null renderer callback to the channel and 3d mixer input bus
                    for (uint i = 0; i < MaxNumberOfTracks; i++)
                    {
                        CheckUnitStatus((AudioUnitStatus)SetInputRenderCallbackToNull(unit3DMixer.Handle, i), "Failed to set the render callback");
                        CheckUnitStatus((AudioUnitStatus)SetInputRenderCallbackToNull(unitChannelMixer.Handle, i), "Failed to set the render callback");
                    }

                    // Initialize the graph (validation of the topology)
                    CheckGraphError(audioGraph.Initialize(), "The audio graph initialization failed.");

                    // Start audio rendering
                    CheckGraphError(audioGraph.Start(), "Audio Graph could not start.");

                    // disable all the input bus at the beginning
                    for (uint i = 0; i < MaxNumberOfTracks; i++)
                    {
                        CheckUnitStatus(unitChannelMixer.SetParameter(AudioUnitParameterType.MultiChannelMixerEnable, 0f, AudioUnitScopeType.Input, i), "Failed to enable/disable the ChannelMixerInput.");
                        CheckUnitStatus(unit3DMixer.SetParameter(AudioUnitParameterType.Mixer3DEnable, 0f, AudioUnitScopeType.Input, i), "Failed to enable/disable the 3DMixerInput.");
                    }

                    // At initialization all UnitElement are available.
                    availableMixerBusIndices = new Queue <uint>();
                    for (uint i = 0; i < MaxNumberOfTracks; i++)
                    {
                        availableMixerBusIndices.Enqueue(i);
                    }
                }
                ++nbOfInstances;

                // Create a AudioDataRendererInfo for the sounds.
                pAudioDataRendererInfo = (AudioDataRendererInfo *)Utilities.AllocateClearedMemory(sizeof(AudioDataRendererInfo));
                pAudioDataRendererInfo->HandleChannelMixer = unitChannelMixer.Handle;
                pAudioDataRendererInfo->Handle3DMixer      = unit3DMixer.Handle;
            }
        }
		void StreamPropertyListenerProc (object sender, PropertyFoundEventArgs args)
		{
			if (args.Property == AudioFileStreamProperty.DataFormat) {
				dataFormat = audioFileStream.DataFormat;
				return;
			}

			if (args.Property != AudioFileStreamProperty.ReadyToProducePackets)
				return;

			if (audioQueue != null) {
				// TODO: dispose old queue and its tap
				throw new NotImplementedException ();
			}

			audioQueue = new OutputAudioQueue (dataFormat);
			audioQueue.BufferCompleted += HandleBufferCompleted;

			AudioQueueStatus status;
			aqTap = audioQueue.CreateProcessingTap (TapProc, AudioQueueProcessingTapFlags.PreEffects, out status);
			if (status != AudioQueueStatus.Ok)
				throw new ApplicationException ("Could not create AQ tap");

			// create an augraph to process in the tap. needs to convert from tapFormat to effect format and back
			/* note: this is invalidname's recipe to do an in-place effect when a format conversion is needed
			before and after the effect, usually because effects want floats, and everything else in iOS
			core audio works with ints (or, in rare cases, fixed-point).
			the graph looks like this:
			[render-callback] -> [converter] -> [effect] -> [converter] -> [generic-output]
			prior to calling AudioUnitRender() on generic-output the ioData to a pointer that render-callback
			knows about, and NULLs the ioData provided to AudioUnitRender(). the NULL tells generic-output to
			pull from its upstream units (ie, the augraph), and copying off the ioData pointer allows the
			render-callback	to provide it to the front of the stream. in some locales, this kind of shell game
			is described as "batshit crazy", but it seems to work pretty well in practice.
			*/

			auGraph = new AUGraph ();
			auGraph.Open ();
			int effectNode = auGraph.AddNode (AudioComponentDescription.CreateConverter (AudioTypeConverter.NewTimePitch));
			effectUnit = auGraph.GetNodeInfo (effectNode);

			int convertToEffectNode = auGraph.AddNode (AudioComponentDescription.CreateConverter (AudioTypeConverter.AU));
			convertToEffectUnit = auGraph.GetNodeInfo (convertToEffectNode);

			int convertFromEffectNode = auGraph.AddNode (AudioComponentDescription.CreateConverter (AudioTypeConverter.AU));
			convertFromEffectUnit = auGraph.GetNodeInfo (convertFromEffectNode);

			int genericOutputNode = auGraph.AddNode (AudioComponentDescription.CreateOutput (AudioTypeOutput.Generic));
			genericOutputUnit = auGraph.GetNodeInfo (genericOutputNode);

			// set the format conversions throughout the graph
			AudioStreamBasicDescription effectFormat = effectUnit.GetAudioFormat (AudioUnitScopeType.Output);
			var tapFormat = aqTap.ProcessingFormat;

			convertToEffectUnit.SetAudioFormat (tapFormat, AudioUnitScopeType.Input);
			convertToEffectUnit.SetAudioFormat (effectFormat, AudioUnitScopeType.Output);

			convertFromEffectUnit.SetAudioFormat (effectFormat, AudioUnitScopeType.Input);
			convertFromEffectUnit.SetAudioFormat (tapFormat, AudioUnitScopeType.Output);

			genericOutputUnit.SetAudioFormat (tapFormat, AudioUnitScopeType.Input);
			genericOutputUnit.SetAudioFormat (tapFormat, AudioUnitScopeType.Output);

			// set maximum fames per slice higher (4096) so we don't get kAudioUnitErr_TooManyFramesToProcess
			const uint maxFramesPerSlice = 4096;
			if (convertToEffectUnit.SetMaximumFramesPerSlice (maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
				throw new ApplicationException ();
			if (effectUnit.SetMaximumFramesPerSlice (maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
				throw new ApplicationException ();
			if (convertFromEffectUnit.SetMaximumFramesPerSlice (maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
				throw new ApplicationException ();
			if (genericOutputUnit.SetMaximumFramesPerSlice (maxFramesPerSlice, AudioUnitScopeType.Global) != AudioUnitStatus.OK)
				throw new ApplicationException ();

			// connect the nodes
			AUGraphError err = auGraph.ConnnectNodeInput (convertToEffectNode, 0, effectNode, 0);
			if (err != AUGraphError.OK)
				throw new InvalidOperationException ();

			err = auGraph.ConnnectNodeInput (effectNode, 0, convertFromEffectNode, 0);
			if (err != AUGraphError.OK)
				throw new InvalidOperationException ();

			err = auGraph.ConnnectNodeInput (convertFromEffectNode, 0, genericOutputNode, 0);
			if (err != AUGraphError.OK)
				throw new InvalidOperationException ();

			renderTimeStamp.SampleTime = 0;
			renderTimeStamp.Flags = AudioTimeStamp.AtsFlags.SampleTimeValid;

			// set up the callback into the first convert unit
			if (convertToEffectUnit.SetRenderCallback (ConvertInputRenderCallback, AudioUnitScopeType.Global) != AudioUnitStatus.NoError)
				throw new ApplicationException ();

			var res = auGraph.Initialize ();
			if (res != AUGraphError.OK)
				throw new ApplicationException ();
		}
		void PrepareAudioUnit()
		{
			// All iPhones and iPads have microphones, but early iPod touches did not
			if (!AudioSession.AudioInputAvailable) {
				var noInputAlert = new UIAlertView ("No audio input", "No audio input device is currently attached", null, "Ok");
				noInputAlert.Show ();
				return;
			}

			// Getting AudioComponent Remote output
			audioComponent = AudioComponent.FindComponent(AudioTypeOutput.Remote);
			CheckValue (audioComponent);

			// creating an audio unit instance
			audioUnit = new AudioUnit.AudioUnit(audioComponent);

			AudioUnitStatus status;
			status = audioUnit.SetEnableIO(true, AudioUnitScopeType.Input, 1);
			CheckStatus (status);
			status = audioUnit.SetEnableIO(true, AudioUnitScopeType.Output, 0);
			CheckStatus (status);

			dstFormat = new AudioStreamBasicDescription {
				SampleRate = AudioSession.CurrentHardwareSampleRate,
				Format = AudioFormatType.LinearPCM,
				FormatFlags = AudioFormatFlags.IsSignedInteger | AudioFormatFlags.IsNonInterleaved,
				BytesPerPacket = 4,
				FramesPerPacket = 1,
				BytesPerFrame = 4,
				ChannelsPerFrame = 2,
				BitsPerChannel = 16
			};

			audioUnit.SetAudioFormat(dstFormat, AudioUnitScopeType.Input, 0);
			audioUnit.SetAudioFormat(dstFormat, AudioUnitScopeType.Output, 1);

			status = audioUnit.SetRenderCallback(RenderCallback, AudioUnitScopeType.Input, 0);
			CheckStatus (status);
		}
Ejemplo n.º 24
0
        public AudioVoice(AudioEngine engine, SoundEffectInstance effectInstance, WaveFormat desiredFormat)
        {
            if (engine == null) throw new ArgumentNullException("engine");
            if (desiredFormat == null) throw new ArgumentNullException("desiredFormat");

            audioEngine = engine;
            soundEffectInstance = effectInstance;
            waveFormat = desiredFormat;
            BusIndexMixer = uint.MaxValue;

            if (desiredFormat.BitsPerSample != 16)
                throw new AudioSystemInternalException("Invalid Audio Format. " + desiredFormat.BitsPerSample + " bits by sample is not supported.");

            lock (StaticMembersLock)
            {
                if (nbOfInstances == 0)
                {
                    // Create the Audio Graph
                    audioGraph = new AUGraph();

                    // Open the graph (does not initialize it yet)
                    audioGraph.Open();
                    
                    // Create the AudioComponentDescrition corresponding to the IO Remote output and MultiChannelMixer 
                    var remoteInOutComponentDesc = AudioComponentDescription.CreateOutput(AudioTypeOutput.Remote);
                    var mixerMultiChannelComponentDesc = AudioComponentDescription.CreateMixer(AudioTypeMixer.MultiChannel);
                    var mixer3DComponentDesc = AudioComponentDescription.CreateMixer(AudioTypeMixer.Spacial);

                    // Add the Audio Unit nodes to the AudioGraph
                    var outputUnitNodeId = audioGraph.AddNode(remoteInOutComponentDesc);
                    var idChannelMixerNode = audioGraph.AddNode(mixerMultiChannelComponentDesc);
                    var id3DMixerNode = audioGraph.AddNode(mixer3DComponentDesc);

                    // Connect the nodes together
                    CheckGraphError(audioGraph.ConnnectNodeInput(idChannelMixerNode, 0, outputUnitNodeId, 0), "Connection of the graph node failed.");
                    CheckGraphError(audioGraph.ConnnectNodeInput(id3DMixerNode, 0, idChannelMixerNode, MaxNumberOfTracks), "Connection of the graph node failed.");

                    // Get the MixerUnit objects
                    unitChannelMixer = audioGraph.GetNodeInfo(idChannelMixerNode);
                    unit3DMixer = audioGraph.GetNodeInfo(id3DMixerNode);
                    
                    // Set the mixers' output formats (the stream format is propagated along the linked input during the graph initialization)
                    var desiredSampleRate = (engine.AudioSampleRate != 0) ? engine.AudioSampleRate : AudioUnitOutputSampleRate;
                    unit3DMixer.SetAudioFormat(CreateLinear16BitsPcm(2, desiredSampleRate), AudioUnitScopeType.Output);
                    unitChannelMixer.SetAudioFormat(CreateLinear16BitsPcm(2, desiredSampleRate), AudioUnitScopeType.Output);

                    // set the element count to the max number of possible tracks before initializing the audio graph
                    CheckUnitStatus(unitChannelMixer.SetElementCount(AudioUnitScopeType.Input, MaxNumberOfTracks+1), string.Format("Failed to set element count on ChannelMixer [{0}]", MaxNumberOfTracks+1)); // +1 for the 3DMixer output
                    CheckUnitStatus(unit3DMixer.SetElementCount(AudioUnitScopeType.Input, MaxNumberOfTracks), string.Format("Failed to set element count on 3DMixer [{0}]", MaxNumberOfTracks));

                    // set a null renderer callback to the channel and 3d mixer input bus
                    for (uint i = 0; i < MaxNumberOfTracks; i++)
                    {
                        CheckUnitStatus((AudioUnitStatus)SetInputRenderCallbackToNull(unit3DMixer.Handle, i), "Failed to set the render callback");
                        CheckUnitStatus((AudioUnitStatus)SetInputRenderCallbackToNull(unitChannelMixer.Handle, i), "Failed to set the render callback");
                    }
                    
                    // Initialize the graph (validation of the topology)
                    CheckGraphError(audioGraph.Initialize(), "The audio graph initialization failed.");

                    // Start audio rendering
                    CheckGraphError(audioGraph.Start(), "Audio Graph could not start.");

                    // disable all the input bus at the beginning
                    for (uint i = 0; i < MaxNumberOfTracks; i++)
                    {
                        CheckUnitStatus(unitChannelMixer.SetParameter(AudioUnitParameterType.MultiChannelMixerEnable, 0f, AudioUnitScopeType.Input, i), "Failed to enable/disable the ChannelMixerInput.");
                        CheckUnitStatus(unit3DMixer.SetParameter(AudioUnitParameterType.Mixer3DEnable, 0f, AudioUnitScopeType.Input, i), "Failed to enable/disable the 3DMixerInput.");
                    }

                    // At initialization all UnitElement are available.
                    availableMixerBusIndices = new Queue<uint>();
                    for (uint i = 0; i < MaxNumberOfTracks; i++)
                        availableMixerBusIndices.Enqueue(i);
                }
                ++nbOfInstances;

                // Create a AudioDataRendererInfo for the sounds.
                pAudioDataRendererInfo = (AudioDataRendererInfo*)Utilities.AllocateClearedMemory(sizeof(AudioDataRendererInfo));
                pAudioDataRendererInfo->HandleChannelMixer = unitChannelMixer.Handle;
                pAudioDataRendererInfo->Handle3DMixer = unit3DMixer.Handle;
            }
        }
Ejemplo n.º 25
0
        public void InitializeAUGraph()
        {
            Debug.Print("Initialize");

            LoadFiles();

            graph = new AUGraph();

            // create two AudioComponentDescriptions for the AUs we want in the graph

            // output unit
            var outputNode = graph.AddNode(AudioComponentDescription.CreateOutput(AudioTypeOutput.Remote));

            // mixer node
            var mixerNode = graph.AddNode(AudioComponentDescription.CreateMixer(AudioTypeMixer.MultiChannel));

            // connect a node's output to a node's input
            if (graph.ConnnectNodeInput(mixerNode, 0, outputNode, 0) != AUGraphError.OK)
            {
                throw new ApplicationException();
            }

            // open the graph AudioUnits are open but not initialized (no resource allocation occurs here)
            if (graph.TryOpen() != 0)
            {
                throw new ApplicationException();
            }

            mixer = graph.GetNodeInfo(mixerNode);

            // set bus count
            const uint numbuses = 2;

            Debug.Print("Set input bus count {0}", numbuses);

            if (mixer.SetElementCount(AudioUnitScopeType.Input, numbuses) != AudioUnitStatus.OK)
            {
                throw new ApplicationException();
            }

            AudioStreamBasicDescription desc;

            for (uint i = 0; i < numbuses; ++i)
            {
                // setup render callback
                if (graph.SetNodeInputCallback(mixerNode, i, HandleRenderDelegate) != AUGraphError.OK)
                {
                    throw new ApplicationException();
                }

                // set input stream format to what we want
                desc = mixer.GetAudioFormat(AudioUnitScopeType.Input, i);
                //desc.ChangeNumberChannels(2, false);
                desc.SampleRate = GraphSampleRate;

                mixer.SetAudioFormat(desc, AudioUnitScopeType.Input, i);
            }

            // set output stream format to what we want
            desc = mixer.GetAudioFormat(AudioUnitScopeType.Output);

            //desc.ChangeNumberChannels(2, false);
            desc.SampleRate = GraphSampleRate;

            mixer.SetAudioFormat(desc, AudioUnitScopeType.Output);

            // now that we've set everything up we can initialize the graph, this will also validate the connections
            if (graph.Initialize() != AUGraphError.OK)
            {
                throw new ApplicationException();
            }
        }
		public void InitializeAUGraph ()
		{
			Debug.Print ("Initialize");

			LoadFiles ();

			graph = new AUGraph ();

			// create two AudioComponentDescriptions for the AUs we want in the graph

			// output unit
			var outputNode = graph.AddNode (AudioComponentDescription.CreateOutput (AudioTypeOutput.Remote));

			// mixer node
			var mixerNode = graph.AddNode (AudioComponentDescription.CreateMixer (AudioTypeMixer.MultiChannel));

			// connect a node's output to a node's input
			if (graph.ConnnectNodeInput (mixerNode, 0, outputNode, 0) != AUGraphError.OK)
				throw new ApplicationException ();

			// open the graph AudioUnits are open but not initialized (no resource allocation occurs here)
			if (graph.TryOpen () != 0)
				throw new ApplicationException ();

			mixer = graph.GetNodeInfo (mixerNode);

			// set bus count
			const uint numbuses = 2;

			Debug.Print ("Set input bus count {0}", numbuses);

			if (mixer.SetElementCount (AudioUnitScopeType.Input, numbuses) != AudioUnitStatus.OK)
				throw new ApplicationException ();

			AudioStreamBasicDescription desc;

			for (uint i = 0; i < numbuses; ++i) {
				// setup render callback
				if (graph.SetNodeInputCallback (mixerNode, i, HandleRenderDelegate) != AUGraphError.OK)
					throw new ApplicationException ();

				// set input stream format to what we want
				desc = mixer.GetAudioFormat (AudioUnitScopeType.Input, i);
				//desc.ChangeNumberChannels(2, false);
				desc.SampleRate = GraphSampleRate;

				mixer.SetAudioFormat (desc, AudioUnitScopeType.Input, i);
			}

			// set output stream format to what we want
			desc = mixer.GetAudioFormat (AudioUnitScopeType.Output);

			//desc.ChangeNumberChannels(2, false);
			desc.SampleRate = GraphSampleRate;

			mixer.SetAudioFormat (desc, AudioUnitScopeType.Output);

			// now that we've set everything up we can initialize the graph, this will also validate the connections
			if (graph.Initialize () != AUGraphError.OK)
				throw new ApplicationException ();
		}