As is stated in Apple documents:
enum {
MPMusicRepeatModeDefault,
MPMusicRepeatModeNone,
MPMusicRepeatModeOne,
MPMusicRepeatModeAll
};
typedef NSInteger MPMusicRepeatMode;
Yet, MPMusicRepeatModeDefault is described as The user’s preferred repeat mode. Since I am writing a music player I require to know every time what is the current repeat mode, and when this is returned, what of the "actual" modes:
MPMusicRepeatModeNone
MPMusicRepeatModeOne
MPMusicRepeatModeAll
shall be chosen? Or is there no way to get such information?
My understanding is that MPMusicRepeatModeDefault is only used for instantiating your own player as described here.
MPMusicPlayerController* appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
// Use whatever the user has set in their iPod settings
// Omitting this line has no real effect because deferring to the
// user mode is the default setting for new players
[appMusicPlayer setRepeatMode: MPMusicRepeatModeDefault];
If you want to know what that default setting actually is, you should be able to get it from the iPodMusicPlayer instance:
MPMusicPlayerController* iPodMusicPlayer =
[MPMusicPlayerController iPodMusicPlayer];
MPMusicRepeatMode theDefaultMode = [iPodMusicPlayer repeatMode];
Related
I want to detect multiple faces in my project. Therefore I planned to use the trackingID property of the CIFaceFure to keep the track of the face. But I found that every time it is coming same for every face.
So my problem is that how can I identify a face uniquely when multiple face are there in the video frame. I don't want to recognize the face for later purpose only detection for the current video frame. Thanks.
I am using the same code as in SqaureCam apple sample project. in iOS 6.
for ( CIFaceFeature *face in features ) {
NSLog(#"face.trackingID %d",face.trackingID);
}
The above code is priting the same ID for every face.
If you haven't already done so, you need to make sure to specify the usage of CIDetectorTracking in the detector's options. If I remember correctly, it should look something like this:
NSDictionary *detectorOptions = #{CIDetectorTracking: #YES};
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:detectorOptions];
i'm back with one more question related to BASS. I already had posted this question How Can we control bass of music in iPhone, but not get as much attention of your people as it should get. But now I have done some more search and had read the Core AUDIO. I got one sample code which i want to share with you people here is the link to download it iPhoneMixerEqGraphTest. Have a look on it in this code what i had seen is the developer had use preset Equalizer given by iPod in Apple. Lets see some code snippet too:----
// iPodEQ unit
CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);
What kAudioUnitSubType_AUiPodEQ does is it get preset values from iPod's equalizer and return us in Xcode in an array which we can use in PickerView/TableView and can set any category like bass, rock, Dance etc. It is helpless for me as it only returns names of equalizer types like bass, rock, Dance etc. as i want to implement bass only and want to implement it on UISLider.
To implement Bass on slider i need values so that i can set minimum and maximum value so that on moving slider bass can be changed.
After getting all this i start reading Core Audio's Audio Unit framework's classes and got this
after that i start searching for bass control and got this
So now i need to implement this kAudioUnitSubType_LowShelfFilter. But now i don't know how to implement this enum in my code so that i can control the bass as written documentation. Even Apple had not write that how can we use it. kAudioUnitSubType_AUiPodEQ this category was returning us an array but kAudioUnitSubType_LowShelfFilter category is not returning any array. While using kAudioUnitSubType_AUiPodEQ this category we can use types of equalizer from an array but how can we use this category kAudioUnitSubType_LowShelfFilter. Can anybody help me regarding this in any manner? It would be highly appreciable.
Thanks.
Update
Although it's declared in the iOS headers, the Low Shelf AU is not actually available on iOS.
The parameters of the Low Shelf are different from the iPod EQ.
Parameters are declared and documented in `AudioUnit/AudioUnitParameters.h':
// Parameters for the AULowShelfFilter unit
enum {
// Global, Hz, 10->200, 80
kAULowShelfParam_CutoffFrequency = 0,
// Global, dB, -40->40, 0
kAULowShelfParam_Gain = 1
};
So after your low shelf AU is created, configure its parameters using AudioUnitSetParameter.
Some initial parameter values you can try would be 120 Hz (kAULowShelfParam_CutoffFrequency) and +6 dB (kAULowShelfParam_Gain) -- assuming your system reproduces bass well, your low frequency content should be twice as loud.
Can u tell me how can i use this kAULowShelfParam_CutoffFrequency to change the frequency.
If everything is configured right, this should be all that is needed:
assert(lowShelfAU);
const float frequencyInHz = 120.0f;
OSStatus result = AudioUnitSetParameter(lowShelfAU,
kAULowShelfParam_CutoffFrequency,
kAudioUnitScope_Global,
0,
frequencyInHz,
0);
if (noErr != result) {
assert(0 && "error!");
return ...;
}
I am trying to do a certain action based on whether or not the user makes a loud sound. I'm not trying to do any voice recognition or anything. Just simply do an action based on whether the iPhone picks up a loud sound.
Any suggestions, tutorials, I can't find anything on the apple developer site. I'm assuming i'm not looking or searching right.
The easiest thing for you do is to use the AudioQueue services. Here's the manual:
Apple AQ manual
Basically, look for any example code that initialized things with AudioQueueNewInput(). Something like this:
Status = AudioQueueNewInput(&_Description,
Audio_Input_Buffer_Ready,
self,
NULL,
NULL,
0,
&self->Queue);
Once you have that going, you can enable sound level metering with something like this:
// Turn on level metering (iOS 2.0 and later)
UInt32 on = 1;
AudioQueueSetProperty(self->Queue,kAudioQueueProperty_EnableLevelMetering,&on,sizeof(on));
You will have a callback routine that is invoked for each chunk of audio data. In it, you can check the current meter levels with something like this:
//
// Check metering levels and detect silence
//
AudioQueueLevelMeterState meters[1];
UInt32 dlen = sizeof(meters);
Status = AudioQueueGetProperty(_Queue,kAudioQueueProperty_CurrentLevelMeterDB,meters,&dlen);
if (Status == 0) {
if (meters[0].mPeakPower > _threshold) {
silence = 0.0; // reset silence timer
} else {
silence += time;
}
}
//
// Notify observers of incoming data.
//
if (delegate) {
[delegate audioMeter:meters[0].mPeakPower duration:time];
[delegate audioData:Buffer->mAudioData size:Buffer->mAudioDataByteSize];
}
Or, in your case, instead of silence you can detect if the decibel level is over a certain value for long enough. Note that the decibel values you will see will range from about -70.0 for dead silence, up to 0.0db for very loud things. On an exponential scale. You'll have to play with it to see what values work for your particular application.
Apple has examples such as Speak Here which looks to have code relating to decibels. I would check some of the meter classes for examples. I have no audio programming experience but hopefully that will get you started while someone provides you with a better answer.
I'm using the MPMoviePlayer to play a movie. I want to be able to play the movie and allow the user to skip to a certain time in the film at the press of a button.
I'm setting the currentPlaybackTime property of the player but it doesn't seem to work. Instead it simply stats the movie from the beginning no matter what value I use.
Also I log the currentPlaybackTime property through a button click, it always returns a large number but it sometimes returns a minus value?! is this expected? (e.g. -227361412)
Sample code below:
- (IBAction) playShake
{
NSLog(#"playback time = %d",playerIdle.currentPlaybackTime);
[self.playerIdle setCurrentPlaybackTime:2.0];
return;
}
I have successfully used this method of skipping to a point in a movie in the past. I suspect that your issue is actually with the video itself. When you set the currentPlaybackTime MPMoviePlayer will skip to the nearest keyframe in the video. If the video has few keyframes or you're only skipping forward a few seconds this could cause the video to start over from the beginning when you change the currentPlaybackTime.
-currentPlaybackTime returns a NSTimeInterval (double) which you are printing as a signed int. This will result in unexpected values. Try either casting to int (int)playerIdle.currentPlaybackTime or printing the double %1.3f.
I just can't figure out how this works. What I am trying to do is let two players play a game if a third player joins it can instantly join the game, if the fourth and last player joins it can also instantly join the game. They can also leave the game at anytime for whatever reason, if that happens there should be a space open for another person or for the same person to reconnect. That's the idea.
Now what I got is the following. I authenticate the local player for obvious reasons. Then I search for a match like so:
if (matchRequest) [matchRequest release];
matchRequest = [[GKMatchRequest alloc] init];
matchRequest.minPlayers = 2;
matchRequest.maxPlayers = 4;
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:matchRequest withCompletionHandler:^(GKMatch *match, NSError *error) {
if (error) {
// An error occured
} else {
if (matchCurrent) [matchCurrent release];
matchCurrent = [match retain];
matchCurrent.delegate = self;
}
}];
If I execute this part on three different devices, two of them will find each other and the third is still looking. So I figured after the find match for request has found the minimum amount of players it will be executed once. So what I needed was a method that used the matchCurrent that I retained to add more players. Luckely that method existed, but how would that work? When do you call it in this case? I decided to put it under a button so I could manually execute it when a match has been found.
What I discovered is that when I pressed it on the first device, finally the third device could find the match the first and second device were in. In fact the second and third device contained the playerIDs of every device involved. Which is a good thing. But there are two problems.
Which device should actually call the addPlayersToMatch method? And how can you restrict it to one device executing that method? Plus when should you call it?
Why, on the device calling that method, isn't the playerIDs updated?
[[GKMatchmaker sharedMatchmaker] addPlayersToMatch:matchCurrent matchRequest:matchRequest completionHandler:^(NSError *error) {
//matchCurrent.playerIDs is not updated?!
}];
Actually they are updated. When I see the playerIDs appear on the second and third device I manually update the matchCurrent.playerIDs on device one and suddenly it does recognize the player. However even the 'didChangeState' for player is not called when the new player is discovered on device one.
Your using the Apple iOS Game Center GKMatchmaker class. I'm assuming you are using a peer to peer connection, not hosted.
The GKMatch class gives the playerIDs array to you.
#property(nonatomic, readonly) NSArray *playerIDs
This is an ordered list, so you might be able to use it to select the first player call addPlayersToMatch.
Linked below is some documentation.
http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatchmaker_Ref/Reference/Reference.html
http://developer.apple.com/library/ios/#documentation/GameKit/Reference/GKMatch_Ref/Reference/Reference.html
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008304
Which device should actually call the
addPlayersToMatch method? And how can
you restrict it to one device
executing that method?
You could solve this problem by having the devices "draw straws". Each device generates a random number, then sends it to the others. The device with the largest number is the leader, and it is the one that must call addPlayersToMatch. If two devices pick the same number, throw out the numbers and start over.
I would suggest that you periodically (maybe once per second or two) poll for the status of other players, so you can detect if anyone has joined, or left for any reason. Unless the iphone architecture you are using already provides an function that handles that event.
It sounds like you may want to find some more documentation and/or sample code for the multi-player framework you are using.
I'm doing this with Unity via Prime31's GameCenterMultiplayerBinding. I'm not entirely sure how it maps to GameKit (the docs are sparse and don't give those details), but the names are very suggestive.
To be able to match 2 to 4 players into a match, I'm doing:
findMatchProgrammaticallyWithFilters(
minPlayers: 2,
maxPlayers: 4,
playerGroup: GetCurrentPlayerGroup(),
playerAttributes: 0);
I assume this maps to findMatchForRequest:withCompletionHandler.
After that succeeds, I call:
finishMatchmakingForMatch();
Which surely maps to finishMatchmakingForMatch. I found that calling findMatchForRequest or addPlayersToMatch would fail with "The requested operation has been canceled or disabled by the user" if I didn't call finishMatchmakingForMatch first.
addPlayersToCurrentMatchWithUpdatedMatchRequest(
minPlayers: 2,
maxPlayers: 4,
playerGroup: GetCurrentPlayerGroup(),
playerAttributes: 0,
playersToInvite: null);
addPlayersToMatch:matchRequest:completionHandler
After that succeeds, I call:
finishMatchmakingForMatch();
If I have space for more players, I loop and call addPlayersToMatch again.
I'd expect that since I need to call finishMatchmakingForMatch when I'm done
matchmaking, firing findMatchProgrammatically would keep looking until it
found maxPlayers, but it doesn't. It gives up after the first match. So we need
to call addPlayersToMatch.