| 229 | int AudioOutputCA::GetAudiotime(void) |
| 230 | { |
| 231 | /* Returns the current timecode of audio leaving the soundcard, based |
| 232 | on the 'audiotime' computed earlier, and the delay since it was computed. |
| 233 | |
| 234 | This is a little roundabout... |
| 235 | |
| 236 | The reason is that computing 'audiotime' requires acquiring the audio |
| 237 | lock, which the video thread should not do. So, we call 'SetAudioTime()' |
| 238 | from the audio thread, and then call this from the video thread. */ |
| 239 | int ret; |
| 240 | |
| 241 | if (GetBaseAudioTime() == 0) |
| 242 | return 0; |
| 243 | |
| 244 | UInt64 hostNanos = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); |
| 245 | ret = (hostNanos / 1000000) - CA_audiotime_updated; |
| 246 | |
| 247 | ret += GetBaseAudioTime(); |
| 248 | |
| 249 | return ret; |
| 250 | } |
| 251 | |
| 252 | void AudioOutputCA::SetAudiotime(void) |
| 253 | { |
| 254 | if (GetBaseAudBufTimeCode() == 0) |
| 255 | return; |
| 256 | |
| 257 | int soundcard_buffer = 0; |
| 258 | int totalbuffer; |
| 259 | |
| 260 | /* We want to calculate 'audiotime', which is the timestamp of the audio |
| 261 | which is leaving the sound card at this instant. |
| 262 | |
| 263 | We use these variables: |
| 264 | |
| 265 | 'effdsp' is samples/sec, multiplied by 100. |
| 266 | Bytes per sample is assumed to be 4. |
| 267 | |
| 268 | 'audiotimecode' is the timecode of the audio that has just been |
| 269 | written into the buffer. |
| 270 | |
| 271 | 'totalbuffer' is the total # of bytes in our audio buffer, and the |
| 272 | sound card's buffer. |
| 273 | |
| 274 | 'ms/byte' is given by '25000/effdsp'... |
| 275 | */ |
| 276 | |
| 277 | soundcard_buffer = getBufferedOnSoundcard(); // bytes |
| 278 | totalbuffer = audiolen(false) + soundcard_buffer; |
| 279 | |
| 280 | // include algorithmic latencies |
| 281 | if (GetSoundStretch()) |
| 282 | { |
| 283 | // add the effect of unprocessed samples in time stretch algo |
| 284 | totalbuffer += (int)((GetSoundStretch()->numUnprocessedSamples() * |
| 285 | audio_bytes_per_sample) / audio_stretchfactor); |
| 286 | } |
| 287 | |
| 288 | SetBaseAudioTime(GetBaseAudBufTimeCode() - (int)(totalbuffer * 100000.0 / |
| 289 | (audio_bytes_per_sample * effdspstretched))); |
| 290 | |
| 291 | // We also store here the host time stamp of when the update occurred. |
| 292 | // That way when asked later for the audio time we can use the sum of |
| 293 | // the output time code info calculated here and the delta since when it |
| 294 | // was calculated and when we asked. |
| 295 | |
| 296 | // Note that since we're using a single 32bit variable here there is no need to |
| 297 | // use a lock or similar since the 32 bit accesses are atomic. Also we use |
| 298 | // AudioHost time here so that we're all referring to the same clock. |
| 299 | UInt64 hostNanos = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); |
| 300 | CA_audiotime_updated = hostNanos / 1000000; |
| 301 | |
| 302 | } |
| 303 | |