symba (779893), страница 30
Текст из файла (страница 30)
Nevertheless it isworth knowing that DevSound is ‘there’ – even just to understand howthe various APIs link together.In general, CMMFDevSound comes into its own if you are writingmiddleware or adding new MMF plug-ins. That is somewhat beyond thescope of this book – you should consult the relevant documentation inthe Symbian Developer Library and will probably need to seek furtheradvice anyway.5.8 Audio PoliciesIt is sometimes tempting to forget this fact when writing an application,but Symbian OS is a multi-tasking system and there are always some otherprograms running. At various times, your programs may be running in theforeground or in the background – let alone the fact that some servicesare hidden but running continuously.
Having said that, resources on asmartphone are always limited – particularly if special hardware is used tosupport audio codecs. Additionally, however, there are requirements thatsome sounds should be played whatever else is running, for the deviceto be acceptable to consumers – for example, the telephony applicationshould always be able to generate a ringtone.The approach taken by Symbian OS is to allow many programs to playaudio concurrently, without particular consideration as to whether theyare in the foreground or the background – so switching to the backgrounddoes not automatically stop your program’s sound being generated.
Atthe same time, decisions must be made as to what happens when severalclients simultaneously request to play or record. There are several possibleoptions that the device can follow. The basic decision is whether to mixseveral clients together or to decide to play one of them.Another perspective is to consider what happens when a ‘new’ clientwishes to start to play or record:• The new client can be prevented from starting.• Existing clients can be stopped and the new client started.• The new client can be run at the same time as existing clients.If the request concerns playing and the end user is listening to thesound, the end user can usually distinguish this behavior.
However, froma client perspective, you don’t see this – the client is told about when asound is stopped and, by inference, when it plays.So what actually happens? On one level, the options relate to thesoftware and hardware components available. At the time of writing,136MULTIMEDIA FRAMEWORK: AUDIOthe standard Symbian OS emulator on Windows (shipped with manySDK environments) is not capable of mixing and thus can’t supportsimultaneous play. However, a key feature of Symbian OS is that, apartfrom requesting play or record in the first place, neither users nor applications have direct control of what actually happens in these circumstances.The real decision is up to the audio policy of the device – a set of rulesas to what should happen in these scenarios.
This policy is encodedinto a central unit – typically called the audio policy server or the audioresource manager. Applications request to play or record, the decision asto whether they can is made centrally, and that decision is enforced bythe audio adaptation.This shows itself to your client by different error values. For example,a pre-empted player utility gets a MapcPlayComplete() callback withKErrInUse, KErrDied or KErrAccessDenied – the specific errorvalue depends on the adaptation and your code should treat all the same.As with other MapcPlayComplete() callbacks, the player utility is leftin a stopped state.Note that one effect of the API is that there is virtually no differencein calling pattern between two seemingly key scenarios: a new clientrequests to play but this is immediately rejected; and a new applicationrequests to play, starts to play and then is thrown-off (soon) afterwards.Part of the reason for this concerns the asynchronous way that almostall audio APIs request play operations.
When you fire off a play orrecord request, the adaptation returns quite quickly and plays in thebackground – the asynchronous call pattern. The Play() or PlayL(),function call does not wait to find out what happens – so avoiding thelatencies that sometimes occur and keeping the calling client ‘lively’.The disadvantage to this approach is that if, say, you are showing aprogress dialog, it might look to the end user as though play started whenit did not. In reality, we believe that end users are probably not that fussyand that it helps to update playing–stopped buttons, for example, just toshow the command has been accepted. If your application really needsto be fussy, then perhaps wait until some progress has been detected – forexample, the value returned by GetPosition() has changed.What your application should do on pre-emption depends on the usecase.
For sound effects and similar sounds, you’d just forget about it andtreat it as if you’d reached the end anyway – this probably comes forfree, since such client code often ignores failure to play, treating it as anon-fatal error that is not worth telling the client about. At the other endof the scale, on a music player, you will want to change the state of theview to show the player has been stopped and to allow the user to restartfrom the current position – in terms of code, this comes for free.To recap, Symbian OS supports concurrent playing and recording forseveral clients, but what you get depends not only on the hardware’sfeatures but also on what the device manufacturer wants to happen – thePRIORITY SETTINGS137‘policy’. This has a number of implications for you as an applicationwriter:• You must always prepare for audio clients to be pre-empted.• The number of clients you can simultaneously play is dependent onthe particular smartphone model and on what other programs arerunning.5.9 Priority SettingsTo summarize from the previous section, if you fire off several playrequests from your application, it is not really your decision as to whatgets played together.
This raises additional questions, including how theaudio policy knows what to give priority to.The audio policy is based on a combination of what the policy servercan find out about a client process (such as the SecureID of the processand its capabilities) and extra parameters supplied by the client via callssuch as:TInt SetPriority(TInt aPriority, TMdaPriorityPreference aPref);This method is provided by CMdaAudioPlayerUtility. Theseparameters are interpreted as follows:• aPriority is an integer officially between -100 and 100; the internal property defaults to 0.
There are literal values defined for thepriority: EMdaPriorityMin, EMdaPriorityMax and EMdaPriorityNormal. However, any value in the range is usable and, ingeneral, it is easier to define your own constants with associatedvalues.• aPref is slightly more complex. It is best considered as consisting oftwo fields: the lower 16 bits and the upper 16 bits.• The lower 16 bits are flags that state requests about ‘quality’ – whether the stream can be mixed or played at a lowersample rate with another stream. To be honest, these are merelysuggestions – adaptations can and do ignore these flags.
Unlessyou’ve been given additional information, it is probably safest toignore this, supplying 0 as the value for flags.• The upper 16 bits are officially reserved by Symbian for use bymanufacturers. In practice, this means that on the different UIs,there are special values defined with specific meanings.138MULTIMEDIA FRAMEWORK: AUDIOInitially, try just leaving the default behavior and not actually settingthe values – the equivalent of using:SetPriority(EMdaPriorityNormal, EMdaPriorityPreferenceNone);If this does not work, it is probably because you are dealing with oneof the following scenarios:• Another application is running, which is itself using audio clients, andthat is stopping audio for your application.• You want to run several audio clients together, but you know that notall can run on all devices and you give some priority so the importantones generally run.At this point, it is probably worth stepping back a bit and thinking aboutthe overall effect of your decision on the device.
Sounds can perhaps bedivided into three categories:• ‘Must have’ sounds that must be played, usually on their own, or thedevice will not be acceptable to the mobile networks. The obviousexample is the ringtone for incoming calls.• ‘General’ sounds played as part of an application’s core functionality – if your application does not play the sound, the end user will seeit as not working. Examples include a music player not playing tracks.• ‘Additional’ sounds, which add to the richness of a particular application but are not essential and can be omitted without most end usersreally noticing. Obvious examples include key clicks, but additionalthings such as shutter-sound effects for a camera fall into this category.Some scenarios are not quite so easily categorized. Is the backgroundmusic of a game essential? Probably not, but it is worth a thought. Are theexplosion effects of a game essential? Possibly, but again they are wortha thought.So what values do you use? It is up to the built-in software to ensurethat ‘must-have’ sounds are heard.
For ‘general’ sounds, the default isprobably sufficient. For ‘additional’ sounds, a negative number is moreapplicable. Try that and see how it interacts with other applications.5.10Miscellaneous5.10.1 Platform Security and CapabilitiesSymbian OS v9.1 introduced platform security features to stop untrustedor unsigned applications performing key operations.
So the question oftenMISCELLANEOUS139asked is ‘will the platform security features stop me writing an applicationthat plays or records audio?’The simple answer is ‘not really’. Your application doesn’t need anycapabilities to play audio. There is a capability termed MultimediaDDthat is required by some middleware, the adaptation and some keyapplications, but it is very unlikely that your application will need it.Recording is slightly different: the UserEnvironment capability isneeded to record.
If you don’t have it, the RecordL() or another operation fails. However, the UserEnvironment capability is generally setby phone manufacturers to be a user-grantable capability (see Section 2.2for further information).5.10.2 MIDI Player UtilityThere is a special client API, CMidiClientUtility, specifically provided for the playing of MIDI clips from files, etc. This provides muchmore control over playing MIDI, allowing you to change many, if notmost, of the MIDI parameters (choosing instrument banks and the gain ofthe individual channels).The penalty of this API is that it is a lot more complex to usethan CMdaAudioPlayerUtility – for example, there are a lot morecallbacks that need addressing and even more of the operations areasynchronous.