• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2010 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* sync */
18  
19  #include "sles_allinclusive.h"
20  
21  
22  /** \brief Sync thread.
23   *  The sync thread runs periodically to synchronize audio state between
24   *  the application and platform-specific device driver; for best results
25   *  it should run about every graphics frame (e.g. 20 Hz to 50 Hz).
26   */
27  
sync_start(void * arg)28  void *sync_start(void *arg)
29  {
30      CEngine *thiz = (CEngine *) arg;
31      for (;;) {
32  
33          // FIXME should be driven by cond_signal rather than polling,
34          // or at least make the poll interval longer or configurable
35          usleep(20000*5);
36  
37          object_lock_exclusive(&thiz->mObject);
38          if (thiz->mEngine.mShutdown) {
39              thiz->mEngine.mShutdownAck = SL_BOOLEAN_TRUE;
40              // broadcast not signal, because this condition is also used for other purposes
41              object_cond_broadcast(&thiz->mObject);
42              object_unlock_exclusive(&thiz->mObject);
43              break;
44          }
45          if (thiz->m3DCommit.mWaiting) {
46              thiz->m3DCommit.mWaiting = 0;
47              ++thiz->m3DCommit.mGeneration;
48              // There might be more than one thread blocked in Commit, so wake them all
49              object_cond_broadcast(&thiz->mObject);
50              // here is where we would process the enqueued 3D commands
51          }
52          // unsigned instanceMask = thiz->mEngine.mInstanceMask; // for debugger
53          unsigned changedMask = thiz->mEngine.mChangedMask;
54          thiz->mEngine.mChangedMask = 0;
55          object_unlock_exclusive(&thiz->mObject);
56  
57          // now we know which objects exist, and which of those have changes
58  
59          unsigned combinedMask = changedMask /* | instanceMask for debugger */;
60          while (combinedMask) {
61              unsigned i = ctz(combinedMask);
62              assert(MAX_INSTANCE > i);
63              combinedMask &= ~(1 << i);
64              IObject *instance = (IObject *) thiz->mEngine.mInstances[i];
65              // Could be NULL during construct or destroy
66              if (NULL == instance) {
67                  continue;
68              }
69  
70              object_lock_exclusive(instance);
71              unsigned attributesMask = instance->mAttributesMask;
72              instance->mAttributesMask = 0;
73  
74              switch (IObjectToObjectID(instance)) {
75              case SL_OBJECTID_AUDIOPLAYER:
76                  // do something here
77                  object_unlock_exclusive(instance);
78  #ifdef USE_SNDFILE
79                  if (attributesMask & (ATTR_POSITION | ATTR_TRANSPORT)) {
80                      CAudioPlayer *audioPlayer = (CAudioPlayer *) instance;
81                      audioPlayerTransportUpdate(audioPlayer);
82                  }
83  #endif
84                  break;
85  
86              default:
87                  object_unlock_exclusive(instance);
88                  break;
89              }
90          }
91      }
92      return NULL;
93  }
94