IPhone microphone input event capture

Source: Internet
Author: User


Purpose:
Using microphones as an event Input Method
Core:
Use audiosession and audioqueue to capture microphone input data.

Enable audiosession:
1. audiosessioninitialize
2. audiosessionsetproperty (kaudiosessionproperty_audiocategory)
3. audiosessionsetactive

Create sound format:
1. audiostreambasicdescription
2. Use kaudioformatlinearpcm as the sound format

Create audioqueue:
1. audioqueuenewinput
2. audioqueuestart
3. audioqueuesetproperty (kaudioqueueproperty_enablelevelmetering)

Obtain the peak sound data:
1. audioqueuelevelmeterstate
2. audioqueuegetproperty (kaudioqueueproperty_currentlevelmeterdb)

Disable audioqueue:
1. audioqueuestop
2. audioqueuedispose

Code:


# Import <uikit/uikit. h>
# Include <audiotoolbox/audiotoolbox. h>

@ Interface microphonetestviewcontroller: uiviewcontroller {

Iboutlet uilabel * _ averagepower;
Iboutlet uilabel * _ peakpower;

Audioqueueref mqueue;
Audiostreambasicdescription mformat;
Audioqueuelevelmeterstate * _ chan_lvls;
Nsarray * _ channelnumbers;
}

-(Void) setchannelnumbers :( nsarray *) V;
-(Void) initaudiosession;

-(Ibaction) startstop: (ID) sender;

@ End
[/Code]

[Code]
# Import "microphonetestviewcontroller. H"

Static void myinputbufferhandler (void * inuserdata,
Audioqueueref inaq,
Audioqueuebufferref inbuffer,
Const audiotimestamp * instarttime,
Uint32 innumpackets,
Const audiostreampacketdescription * inpacketdesc)
{
// If you want to record the sound, you can record it here.
// If You Want To analyze the sound data, record it here.
}

Static void interruptionlistener (void * inclientdata,
Uint32 ininterruptionstate)
{
// Sound interruption notification (begin, end)
}

@ Implementation microphonetestviewcontroller

// Implement viewdidload to do additional setup after loading the view, typically from a nib.
-(Void) viewdidload {
[Super viewdidload];

_ Averagepower. Text = @ "0 ";
_ Peakpower. Text = @ "0 ";
Mqueue = NULL;
_ Channelnumbers = [[nsarray alloc] initwithobjects: [nsnumber numberwithint: 0], nil];
_ Chan_lvls = (audioqueuelevelmeterstate *) malloc (sizeof (audioqueuelevelmeterstate) * [_ channelnumbers count]);

[Self initaudiosession];

[Nstimer
Scheduledtimerwithtimeinterval: 1.f/ 30.f
Target: Self
Selector: @ selector (_ refresh)
Userinfo: Nil
Repeats: Yes
];
}

-(Void) didreceivememorywarning {
// Releases the view if it doesn't have a superview.
[Super didreceivememorywarning];

// Release any cached data, images, etc that aren't in use.
}

-(Void) viewdidunload {
// Release any retained subviews of the main view.
// E.g. Self. myoutlet = nil;
[_ Channelnumbers release];
Free (_ chan_lvls );
}

-(Void) dealloc {
[Super dealloc];
}

-(Void) initaudiosession
{
Osstatus error = audiosessioninitialize (null, null, interruptionlistener, self );
If (error) printf ("error initializing audio session! % D \ n ", (INT) error );
Else
{
Uint32 Category = kaudiosessioncategory_playandrecord;
Error = audiosessionsetproperty (kaudiosessionproperty_audiocategory, sizeof (category), & category );
If (error) printf ("couldn't set audio category! ");

Error = audiosessionsetactive (true );
If (error) printf ("audiosessionsetactive (true) failed ");
}
}

-(Void) setupaudioformat :( uint32) informatid
{
Memset (& mformat, 0, sizeof (mformat ));

Uint32 size = sizeof (mformat. msamplerate );
Osstatus result = audiosessiongetproperty (kaudiosessionproperty_currenthardwaresamplerate,
& Size,
& Mformat. msamplerate );

Size = sizeof (mformat. mchannelsperframe );
Result = audiosessiongetproperty (kaudiosessionproperty_currenthardwareinputnumberchannels,
& Size,
& Mformat. mchannelsperframe );

Mformat. mformatid = informatid;
If (informatid = kaudioformatlinearpcm)
{
// If we want PCM, default to signed 16-bit little-Endian
Mformat. mformatflags = klinearpcmformatflagissignedinteger | klinearpcmformatflagispacked;
Mformat. mbitsperchannel = 16;
Mformat. mbytesperpacket = mformat. mbytesperframe = (mformat. mbitsperchannel/8) * mformat. mchannelsperframe;
Mformat. mframesperpacket = 1;
}
}

-(Void) startmicrophone
{
[Self setupaudioformat: kaudioformatlinearpcm];
Osstatus result = audioqueuenewinput (& mformat, myinputbufferhandler, null, 0, & mqueue );
If (result = noerr ){
Result = audioqueuestart (mqueue, null );
If (result = noerr ){
Uint32 val = 1;
Audioqueuesetproperty (mqueue, kaudioqueueproperty_enablelevelmetering, & Val, sizeof (uint32 ));

If (mformat. mchannelsperframe! = [_ Channelnumbers count])
{
Nsarray * chan_array;
If (mformat. mchannelsperframe <2)
Chan_array = [[nsarray alloc] initwithobjects: [nsnumber numberwithint: 0], nil];
Else
Chan_array = [[nsarray alloc] initwithobjects: [nsnumber numberwithint: 0], [nsnumber numberwithint: 1], nil];

[Self setchannelnumbers: chan_array];
[Chan_array release];

_ Chan_lvls = (audioqueuelevelmeterstate *) realloc (_ chan_lvls, mformat. mchannelsperframe * sizeof (audioqueuelevelmeterstate ));
}

Return;
}
}

// Failed
Mqueue = NULL;
Nslog (@ "startmicrophone: Failed .");
Return;
}

-(Void) stopmicrophone
{
If (mqueue ){
Audioqueuestop (mqueue, true );
Audioqueuedispose (mqueue, true );
Mqueue = NULL;
}
}

-(Void) _ refresh
{
If (mqueue ){
Uint32 data_sz = sizeof (audioqueuelevelmeterstate) * [_ channelnumbers count];
Oserr status = audioqueuegetproperty (mqueue, kaudioqueueproperty_currentlevelmeterdb, _ chan_lvls, & data_sz );
If (status = noerr)
{
// The data display of multiple channels is not processed here, and the result of the last channel is displayed directly.
// The value here is the value we intend to use as a trigger mechanism. When necessary, access the array _ chan_lvls directly.
For (INT I = 0; I <[_ channelnumbers count]; I ++)
{
Nsinteger channelidx = [(nsnumber *) [_ channelnumbers objectatindex: I] intvalue];
If (channelidx <[_ channelnumbers count] & channelidx <= 127)
{
_ Averagepower. Text = [nsstring stringwithformat: @ "% F", _ chan_lvls [channelidx]. maveragepower];
_ Peakpower. Text = [nsstring stringwithformat: @ "% F", _ chan_lvls [channelidx]. mpeakpower];
}
}
}
}
}

-(Void) setchannelnumbers :( nsarray *) V
{
[V retain];
[_ Channelnumbers release];
_ Channelnumbers = V;
}

-(Ibaction) startstop: (ID) sender
{
If (mqueue ){
[Self stopmicrophone];
} Else {
[Self startmicrophone];
}
}

@ End

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.