OLD | NEW |
---|---|
(Empty) | |
1 # Audio Focus Handling | |
2 | |
3 Audio focus handling is part of the default media session on desktop, which | |
4 manages the mixing of MediaSessions. | |
whywhat
2016/09/27 17:54:17
Expand on what MediaSession is unless we have a do
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
5 | |
6 [TOC] | |
7 | |
8 ## Processing model | |
9 | |
10 ### Audio focus types | |
11 | |
12 There are "persistent" and "transient" audio focus types. Persistent audios | |
13 should not mix with each other and transient audio should play on top of | |
whywhat
2016/09/27 17:54:16
Audio playback with persistent audio focus stops o
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Elaborated a bit here. But we treat Pepper as Pers
| |
14 persistent audio. | |
15 | |
16 ### `MediaSession` | |
17 | |
18 Audio-producing objects should join `MediaSession` when they want to produce | |
19 sound. `MediaSession` has the following states: | |
20 | |
21 * ACTIVE: the `MediaSession` has audio focus and should be play normally. | |
whywhat
2016/09/27 17:54:16
s/be play/be played
What does "normally" mean? Ma
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
22 * SUSPENDED: the MediaSession does not has audio focus. All audio-producing | |
whywhat
2016/09/27 17:54:16
s/has/have
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
23 objects are paused and can be resumed when the session resumes. | |
whywhat
2016/09/27 17:54:16
s/resumes/gains audio focus or is resumed by user?
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
24 * INACTIVE: the MediaSession does not has audio focus, and there is no | |
whywhat
2016/09/27 17:54:16
s/has/have
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
25 audio-producing objects in this `MediaSession`. | |
26 | |
27 Besides, `MediaSession` has a `DUCKING` flag, which means its managed | |
28 audio-producing objects has lowered volume. The flag is orthogonal with | |
29 `MediaSession` state. | |
30 | |
31 ### `AudioFocusManager` | |
32 | |
33 `AudioFocusManager` is a global instance which manages the state of | |
34 `MediaSession`s. | |
35 | |
36 When an audio-producing object wants to play audio, it should join `MediaSession ` | |
37 and tell which kind of audio focus type it requires. `MediaSession` will then | |
38 request audio focus from `AudioFocusManager`, and will allow the object to play | |
39 sound if successful. `AudioFocusManager` will notify other `MediaSession`s if | |
40 their states are changed. | |
41 | |
42 When an audio-producing object stops playing audio, it should be removed from | |
43 its `MediaSession`, and `MediaSession` should abandon its audio focus if there | |
44 are no audio-producing object is managed by it. `AudioFocusManager` will notify | |
whywhat
2016/09/27 17:54:16
s/is// or maybe just say if it's empty?
Zhiqiang Zhang (Slow)
2016/09/28 16:12:17
Done.
| |
45 other `MediaSession`s of state change if necessary. | |
46 | |
47 ## The algorithm for handling audio focus | |
48 | |
49 `AudioFocusManager` uses a stack implementation. It keeps track of all | |
50 ACTIVE/SUSPENDED `MediaSession`s. When a `MediaSession` requests audio focus, it | |
51 will be put at the top of the stack, and will be removed from the stack when it | |
52 abandons audio focus. | |
53 | |
54 The algorithm is as follows: | |
55 | |
56 * When a `MediaSession` requests audio focus: | |
57 | |
58 * Remove it from the audio focus stack, and place it at the top of audio | |
whywhat
2016/09/27 17:54:16
"Remove it from the audio focus stack if it's alre
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Done.
| |
59 focus stack, grant focus to the session and let it play. | |
60 * If the session is persistent, suspend all sessions on the stack | |
whywhat
2016/09/27 17:54:16
s/all/all the other
Zhiqiang Zhang (Slow)
2016/09/28 16:12:17
Done.
| |
61 * If the session is transient: | |
62 | |
63 * If the next top entry is transient, do nothing. | |
64 * If the next top entry is persistent, let the next top entry start ducking. | |
whywhat
2016/09/27 17:54:16
Maybe clarify we took care of the remaining sessio
Zhiqiang Zhang (Slow)
2016/09/28 16:12:18
Sorry, I'm not very sure of what you mean here. Ca
whywhat
2016/09/29 22:40:47
I meant, clarify why we only duck the top session,
| |
65 | |
66 * When a `MediaSession` abandons audio focus: | |
67 | |
68 * If the session is not on the top, just remove it from the stack. | |
69 * If the session is on the top, remove it from the stack. | |
70 | |
71 * If the stack becomes empty, do nothing. | |
72 * If the next top session is transient, do nothing. | |
73 * If the next top session is persistent, stop ducking it. | |
74 | |
75 ### Handling Pepper | |
76 | |
77 Pepper is different from media elements since it has a different model. Pepper | |
78 cannot be paused, but its volume can be changed. When considering Pepper, the | |
79 above algorithm must be modified. | |
80 | |
81 When Pepper joins `MediaSession`, it should request persistent focus type. When | |
82 AudioFocusManager wants to suspend a `MediaSession`, it must check whether the | |
83 session has Pepper instance, and if yes, it should duck the session instead. | |
84 | |
85 Also, whenever a session abandons focus, and the next top session is INACTIVE, | |
86 `AudioFocusManager` should find the next session having Pepper and unduck it. | |
OLD | NEW |