throbber
/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 1/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`+++++¬
`…
`¬2
`Copyright (c) 2001 BeComm Corporation¬
`3
`¬4
`Filename:¬
`5
`¬6
` audiosync.c¬
`7
`¬8
`Group Name:¬
`9
`¬10
`¬11
`¬12
`Overview:¬
`13
`¬14
` This bead adjusts the audio stream by either¬
`15
` dropping data, padding data or resampling data¬
`16
` in an effort to make the path render clock match¬
`17
` the path sample clock.¬
`18
`¬19
` This is done by computing the error in ms,¬
`20
` smoothing the error over successive calls to¬
`21
` the handler to reduce the noise in the signal.¬
`22
` A damping factor is applied to correction to¬
`23
` reduce the likelihood of over correction. Note there¬
`24
` is a significant amount of buffering between this¬
`25
` bead and playout which adds latency to the feedback.¬
`26
` Without damping it would be very possible to over¬
`27
` correct and end up cycling.¬
`28
`¬29
` When a correction value has been found the¬
`30
` stream is modified if necessary to¬
`31
` bring the error back into tolerance.¬
`32
`¬33
` If the audio is very early, the packet is duplicated¬
`34
` as necessary to delay it.¬
`35
`¬36
` If the audio is very late, part or all of the packet¬
`37
` is discarded.¬
`38
`¬39
` If the audio is a little early or late, the packet¬
`40
` is resampled to stretch or shrink it.¬
`41
` ¬
`42
`Notes:¬
`43
`¬44
`
`Page 1 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 2/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
` Currently only supports 16-bit audio streams.¬
`45
` Supporting 8-bits would be relatively trivial.¬
`46
`¬47
`Owner:¬
`48
`¬49
` Guy Carpenter (guyc) 28-Sep-2001¬
`50
`¬51
`--------------------------------------------------------------------------
`52
`---*/¬
`…
`¬53
`#define SOS_DEBUG_ZONE "/beads/audiosync"¬
`54
`¬55
`#include <sosstrings.h>¬
`56
`#include <sosmultimedia.h>¬
`57
`¬58
`SOS_SOURCE_VERSION (¬
`59
` "$Id: audiosync.c,v 1.12 2001/10/23 16:53:51 guyc Exp $"¬
`60
`);¬
`61
`¬62
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`63
`+++++¬
`…
`Named Constants¬
`64
`--------------------------------------------------------------------------
`65
`---*/¬
`…
`¬66
`/*¬
`67
` * Name of bead¬
`68
` */¬
`69
`static const char BEAD_NAME[] = "audiosync";¬
`70
`¬71
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`72
`+++++¬
`…
`Structs¬
`73
`--------------------------------------------------------------------------
`74
`---*/¬
`…
`¬75
`typedef struct {¬
`76
` SOS_UINT32 Size; /* total size we can contain */¬
`77
` SOS_UINT32 Count; /* current number of entries */¬
`78
` SOS_UINT32 Index; /* index of next new value */¬
`79
` SOS_INT32 Sum; /* total of count values */¬
`80
` SOS_INT32 * Value; /* count values */¬
`81
`} SLIDING_AVG;¬
`82
`¬83
`typedef struct {¬
`84
`
`Page 2 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 3/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
` SOS_BOOLEAN ContextReady;¬
`85
` SOS_ISAMPLECLOCK * MasterClock;¬
`86
` SOS_ISAMPLECLOCK * RenderClock;¬
`87
` SOS_IAUDIOCONTEXT * AudioContext;¬
`88
` SLIDING_AVG AvgError;¬
`89
` SOS_BOOLEAN First;¬
`90
`} AUDIOSYNC_CONTEXT;¬
`91
`¬92
`#define EARLY_BAIL_THRESHOLD 5000 /* fail if > N ms early */¬
`93
`#define LATE_BAIL_THRESHOLD 500000 /* fail is < N ms late */¬
`94
`#define EARLY_COPY_THRESHOLD 200 /* duplicate if > N ms early */¬
`95
`#define LATE_DROP_THRESHOLD 200 /* drop if > N ms late */¬
`96
`#define EARLY_RESAMPLE_THRESHOLD 4 /* resample if > N ms early */¬
`97
`#define LATE_RESAMPLE_THRESHOLD 4 /* resample if > N ms late */¬
`98
`¬99
`#define MAX_RESAMPLE_PERCENT 101 /* super-sample up to 1% */¬
`100
`#define MIN_RESAMPLE_PERCENT 99 /* sub-sample up to 1% */¬
`101

`102
`#define EARLY_THRESHOLD EARLY_RESAMPLE_THRESHOLD¬
`103
`#define LATE_THRESHOLD LATE_RESAMPLE_THRESHOLD¬
`104

`105
`#define SMOOTH_FACTOR 8 /* use average of last N errors */¬
`106

`107
`/*¬
`108
` * REVISIT - can this value be determined empirically?¬
`109
` * Could be quite complicated to converge on the smallest¬
`110
` * value that doesn't over-compensate.¬
`111
` */¬
`112
`#define DAMPING_FACTOR 8 /* correction=N/DAMPING_FACTOR */¬
`113

`114
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`115
`+++++¬
`…
`Utility Functions¬
`116
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`117
`+++*/¬
`…

`118
`SOS_UINT32¬
`119
`Scale(¬
`120
` SOS_UINT32 Value,¬
`121
` SOS_UINT32 Numerator,¬
`122
` SOS_UINT32 Denominator¬
`123
`)¬
`124
`{¬
`125
` SOS_UINT32 whole = Value / Denominator;¬
`126
` SOS_UINT32 remain = Value % Denominator;¬
`127
`
`Page 3 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 4/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`128
`…
`129
`130
`131
`132
`133
`…
`134
`135
`…
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`167
`168
`169
`
` SOS_UINT32 result = whole * Numerator + remain * Numerator /
`Denominator;¬
` return result;¬
`}¬


`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Sliding Average Routines¬
`--------------------------------------------------------------------------
`---*/¬
`static¬
`SOS_STATUS¬
`SlidingAvg_Init(¬
` SLIDING_AVG * Avg,¬
` SOS_UINT32 Size¬
`)¬
`{¬
`// SOS_Debug_StringPrint("SlidingAvg_Init\n");¬
` Avg->Value = SOS_Mem_Alloc(sizeof(SOS_UINT32)*Size);¬
` SOS_memset(Avg->Value, 0, sizeof(SLIDING_AVG));¬
` Avg->Size = Size;¬
` return Avg->Value ? SOS_Success : SOS_ErrorResourceAllocation;¬
`}¬

`static¬
`void¬
`SlidingAvg_Uninit(¬
` SLIDING_AVG * Avg¬
`)¬
`{¬
` SOS_Mem_Free(Avg->Value);¬
`}¬
` ¬

`static¬
`SOS_INT32¬
`SlidingAvg_Add(¬
` SLIDING_AVG * Avg,¬
` SOS_INT32 Value¬
`)¬
`{¬
` SOS_DEBUGOUT_DETAIL(¬
` "SlidingAvg_Add gets %ld\n",¬
` Value¬
`
`Page 4 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 5/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`170
`171
`172
`173
`174
`175
`176
`177
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`192
`193
`194
`195
`…
`196
`197
`…
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`212
`
` );¬
` ¬
` if (Avg->Count==Avg->Size) {¬
` Avg->Sum-=Avg->Value[Avg->Index];¬
` } else {¬
` Avg->Count++;¬
` }¬
` Avg->Value[Avg->Index]=Value;¬
` Avg->Sum+=Value;¬

` Avg->Index++;¬
` if (Avg->Index==Avg->Size) {¬
` Avg->Index=0;¬
` }¬

` SOS_DEBUGOUT_DETAIL(¬
` "SlidingAvg_Add returns %ld/%lu=%ld\n",¬
` Avg->Sum,¬
` Avg->Count,¬
` Avg->Sum/(SOS_INT32)Avg->Count¬
` );¬
` return Avg->Sum/(SOS_INT32)Avg->Count;¬
`}¬


`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Context Stuff¬
`--------------------------------------------------------------------------
`---*/¬

`static¬
`void¬
`AudioSync_ContextDestroy(¬
` AUDIOSYNC_CONTEXT * Context¬
`)¬
`{¬
` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_ContextDestroy\n");¬

` if (Context) {¬
` SlidingAvg_Uninit(&(Context->AvgError));¬
` SOS_Interface_Release(Context->MasterClock);¬
` SOS_Interface_Release(Context->RenderClock);¬
` SOS_Interface_Release(Context->AudioContext);¬
` SOS_Mem_Free(Context);¬
`
`Page 5 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 6/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`213
`214
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`233
`234
`235
`236
`…
`237
`238
`…
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`254
`255
`
` }¬
`}¬

`static¬
`AUDIOSYNC_CONTEXT *¬
`AudioSync_ContextCreate(¬
` void¬
`)¬
`{¬
` AUDIOSYNC_CONTEXT *context;¬

` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_ContextCreate\n");¬

` context = SOS_Mem_Alloc(sizeof(*context));¬
` if (context) {¬
` SOS_memset(context, 0, sizeof(*context));¬
` SlidingAvg_Init(&(context->AvgError),SMOOTH_FACTOR);¬
`context->First = SOS_True;¬
` }¬

` return context;¬
`}¬

`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬

`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++*/¬

`static¬
`SOS_STATUS¬
`AudioSync_KeyCreate(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`{¬
` static SOS_UINT32 s_UniqueId = 0;¬
` SOS_REGOBJECT* uniqueSessionKey;¬
` ¬
` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_KeyCreate\n");¬

` uniqueSessionKey = SOS_UInt32_Create(s_UniqueId++);¬
` SOS_Path_SessionKeySet(Path, uniqueSessionKey);¬
` SOS_RegObject_Release(uniqueSessionKey);¬

`
`Page 6 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 7/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`256
`257
`258
`259
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`271
`272
`273
`274
`275
`276
`277
`278
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`297
`298
`299
`300
`
` return SOS_Success;¬
`}¬

`SOS_STATUS¬
`ContextClockGet(¬
` SOS_PATH * Path,¬
` const char * Name,¬
` SOS_ISAMPLECLOCK ** ISampleClock¬
`)¬
`{¬
` SOS_STATUS status;¬
` SOS_REGOBJECT *object;¬
` SOS_ISAMPLECLOCK *iSampleClock = NULL;¬
` ¬
` SOS_DEBUGOUT_FUNC_TRACE("ContextClockGet\n");¬

` status = SOS_Path_AttributeGet(¬
` Path,¬
` Name,¬
` &object¬
` );¬

` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Clock not found"¬
` );¬
` ¬
` if (SOS_SUCCEEDED(status)) {¬
` status = SOS_RegObject_InterfaceGet(¬
` object,¬
` SOS_ISAMPLECLOCK_ID,¬
` (void**)&iSampleClock¬
` );¬
` SOS_RegObject_Release(object);¬
` }¬

` if (ISampleClock) {¬
` *ISampleClock = iSampleClock;¬
` } else {¬
` SOS_Interface_Release(iSampleClock);¬
` status = SOS_ErrorParameter;¬
` }¬

` return status;¬
`}¬
`
`Page 7 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 8/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`301
`302
`303
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`324
`325
`326
`327
`328
`329
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`344
`345
`


`SOS_STATUS¬
`AudioContextGet(¬
` SOS_PATH * Path,¬
` const char * Name,¬
` SOS_IAUDIOCONTEXT ** IAudioContext¬
`)¬
`{¬
` SOS_STATUS status;¬
` SOS_REGOBJECT *contextObject;¬
` SOS_IAUDIOCONTEXT *iAudioContext = NULL;¬
` ¬
` status = SOS_Path_AttributeGet(¬
` Path,¬
` Name,¬
` &contextObject¬
` );¬

` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Path context does not contain an audio context"¬
` );¬
` ¬
` if (SOS_SUCCEEDED(status)) {¬
` status = SOS_RegObject_InterfaceGet(¬
` contextObject,¬
` SOS_IAUDIOCONTEXT_ID,¬
` (void**)&iAudioContext¬
` );¬
` ¬
` SOS_ASSERT_SOFT_ERROR(¬
` SOS_SUCCEEDED(status),¬
` "Audio context does not support required interface"¬
` );¬
` ¬
` SOS_RegObject_Release(contextObject);¬
` }¬

` *IAudioContext = iAudioContext;¬

` return status;¬
`}¬


`
`Page 8 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/be…/…/main/audiosync.c
`Page 9/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`346
`347
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`380
`381
`382
`383
`384
`385
`386
`387
`388
`389
`390
`

`static¬
`SOS_STATUS¬
`AudioSync_ContextPrepare(¬
` AUDIOSYNC_CONTEXT *Context,¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status;¬

` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_ContextPrepare\n");¬

` if (!Context->RenderClock) {¬
` ContextClockGet(¬
` Path,¬
` SOS_RENDERCLOCK_NAME,¬
` &Context->RenderClock¬
` );¬
` }¬

` if (!Context->MasterClock) {¬
` ContextClockGet(¬
` Path,¬
` SOS_MASTERCLOCK_NAME,¬
` &Context->MasterClock¬
` );¬
` }¬

` if (!Context->AudioContext) {¬
` AudioContextGet(¬
` Path,¬
` SOS_AUDIOCONTEXT_NAME,¬
` &Context->AudioContext¬
` );¬
` }¬
` ¬
` /*¬
` * Success only if we got all of the components¬
` */¬
` SOS_DEBUGOUT_DETAIL(¬
` "AudioContext %s MasterClock %s RenderClock %s\n",¬
` Context->AudioContext ? "yes" : "no",¬
` Context->MasterClock ? "yes" : "no",¬
` Context->RenderClock ? "yes" : "no"¬
` );¬
`
`Page 9 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 10/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`391
`392
`393
`394
`395
`396
`397
`398
`399
`400
`…
`401
`402
`…
`403
`404
`405
`406
`407
`408
`409
`410
`411
`412
`413
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`432
`433
`
` ¬
` status = (¬
` Context->AudioContext &&¬
` Context->MasterClock &&¬
` Context->RenderClock) ? SOS_Success : SOS_Error;¬
` ¬
` return status;¬
`}¬

`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Adjustment¬
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++*/¬
`static¬
`SOS_INT32 *¬
`AudioSync_Resample16(¬
` SOS_INT32 * InBuffer,¬
` SOS_UINT32 InCount,¬
` SOS_UINT32 OutCount¬
`)¬
`{¬
` SOS_INT32 * outBuffer = SOS_Mem_Alloc(OutCount * sizeof(SOS_INT32));¬
` SOS_UINT32 i;¬

` if (outBuffer) {¬
` for (i=0;i<OutCount;i++) {¬
` outBuffer[i]=InBuffer[i*InCount/OutCount];¬
` }¬
` }¬
` return outBuffer;¬
`}¬

`static¬
`SOS_STATUS¬
`AudioSync_MessageFill(¬
` SOS_MESSAGE* Message,¬
` char Value¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` size_t length;¬
` void *buffer;¬
` ¬
` length = SOS_Message_LengthGet(Message);¬
`
`Page 10 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 11/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`434
`435
`436
`437
`438
`439
`440
`441
`442
`443
`444
`445
`446
`447
`448
`449
`450
`451
`452
`453
`454
`455
`456
`457
`458
`459
`460
`461
`462
`463
`464
`465
`466
`467
`468
`469
`470
`471
`472
`473
`474
`475
`476
`477
`478
`
` buffer = SOS_Mem_Alloc(length);¬
` ¬
` if (buffer) {¬
` // REVISIT - doesn't handle 8-bit silence¬
` SOS_memset(buffer, Value, length);¬
` SOS_Message_HeadDataPop(¬
` Message,¬
` length,¬
` NULL,¬
` NULL¬
` );¬
` SOS_Message_HeadDataPush(¬
` Message,¬
` buffer,¬
` length,¬
` SOS_Mem_Free¬
` );¬
` ¬
` } else {¬
` status = SOS_Error;¬
` }¬

` return status;¬
`}¬
` ¬
` ¬


`static¬
`SOS_STATUS¬
`AudioSync_Adjust(¬
` AUDIOSYNC_CONTEXT* Context,¬
` SOS_PATH* Path,¬
` SOS_MESSAGE* Message,¬
` SOS_CLOCK_TICK MasterEpoch,¬
` SOS_CLOCK_TICK RenderEpoch¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` SOS_INT32 early = (SOS_INT32)(MasterEpoch-RenderEpoch);¬
` SOS_INT32 avgEarly = SlidingAvg_Add(&(Context->AvgError),early);¬
` SOS_INT32 avgLate = -avgEarly;¬
` SOS_INT32 avgDelta = avgEarly>0 ? avgEarly : -avgEarly;¬

` SOS_DEBUGOUT_DETAIL(¬
`
`Page 11 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 12/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`479
`480
`481
`482
`483
`484
`485
`486
`487
`488
`489
`490
`491
`492
`493
`494
`495
`496
`497
`498
`499
`500
`501
`502
`503
`504
`505
`506
`507
`508
`509
`510
`511
`512
`513
`514
`515
`516
`517
`518
`519
`520
`521
`522
`523
`
` "AudioSync MasterEpoch=%lu RenderEpoch=%lu\n",¬
` MasterEpoch,¬
` RenderEpoch¬
` );¬

` /*¬
` * If master epoch > render epoch then we are early and should delay.¬
` */¬

` SOS_DEBUGOUT_DETAIL(¬
` "AudioSync reports %ld ms %s (avg %ld %s)\n",¬
` early>0 ? early : -early,¬
` early>0 ? "early" : "late",¬
` avgDelta,¬
` avgEarly>0 ? "early" : "late"¬
` );¬


` if (avgLate>LATE_BAIL_THRESHOLD) {¬
` status = SOS_Error;¬
` } else if (avgEarly>EARLY_BAIL_THRESHOLD) {¬
` ¬
` Context->AudioContext->Unpack(¬
` Context->AudioContext,¬
` Message¬
` );¬

` /*¬
` * if it fails to fill the message it¬
` * leaves the message intact, and we return¬
` * the status which causes the message to¬
` * be discarded ultimately (which is fine)¬
` */¬
` status = AudioSync_MessageFill(Message, 0);¬
` ¬
` Context->AudioContext->Pack(¬
` Context->AudioContext,¬
` Message¬
` );¬
` ¬
` } else if (avgEarly>EARLY_THRESHOLD ||¬
` avgLate>LATE_THRESHOLD) {¬
` SOS_AUDIO_FORMAT format;¬
` SOS_UINT32 samples;¬
` SOS_UINT32 bytes;¬
`
`Page 12 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 13/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`524
`525
`526
`527
`528
`529
`530
`531
`532
`533
`534
`535
`536
`537
`538
`539
`540
`541
`542
`543
`544
`545
`546
`547
`548
`549
`550
`551
`552
`553
`554
`555
`556
`557
`558
`559
`560
`561
`562
`563
`564
`565
`566
`567
`568
`
` SOS_UINT32 quantum;¬
` /*¬
` * We are out of tolerance - need to adjust¬
` */¬

` Context->AudioContext->Unpack(¬
` Context->AudioContext,¬
` Message¬
` );¬

` Context->AudioContext->FormatGet(¬
` Context->AudioContext,¬
` NULL, /* no message, we've already unpacked it */¬
` &format¬
` );¬

` SOS_ASSERT_ASSUMPTION(¬
` format.SampleBits==16,¬
` "Currently only supports 16-bit audio resampling"¬
` );¬

` samples = Scale(avgDelta,format.Frequency,SOS_MSPERSECOND);¬
` samples /= DAMPING_FACTOR; /* dampen attack */¬
` quantum = (format.SampleBits+SOS_BITSPERBYTE-1)/¬
` SOS_BITSPERBYTE * format.Channels;¬
` bytes = samples * quantum;¬


`/* SOS_Debug_StringPrint(¬
` "Error is %lu samples, %lu bytes\n",¬
` samples,¬
` bytes¬
` );¬
`*/¬
` ¬
` if (bytes>0) {¬

` if (avgLate > LATE_DROP_THRESHOLD) {¬
` /*¬
` * Data is very late, drop it¬
` */¬
` SOS_Message_HeadDataPop(¬
` Message,¬
` bytes,¬
` NULL,¬
`
`Page 13 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 14/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`569
`570
`571
`572
`573
`574
`575
`576
`577
`578
`579
`580
`581
`582
`583
`584
`585
`586
`587
`588
`589
`590
`591
`592
`593
`594
`595
`596
`597
`598
`599
`600
`601
`602
`603
`604
`605
`606
`607
`608
`609
`610
`611
`…
`612
`
` NULL¬
` );¬

` {// REVISIT - try silencing the fragment¬
` AudioSync_MessageFill(Message, 0);¬
` }¬
` } else if (avgEarly > EARLY_COPY_THRESHOLD) {¬
` /*¬
` * Data is very early, duplicate it enough to¬
` * fill the gap.¬
` */¬
` size_t length = SOS_Message_LengthGet(Message);¬
` while (bytes>0) {¬
` SOS_MESSAGE *append;¬
` size_t take = (bytes < length ? bytes : length);¬
` SOS_Message_HeadMessageCopyFrom(¬
` Message,¬
` take,¬
` &append¬
` );¬
` SOS_Message_TailMessagePush(¬
` Message,¬
` append¬
` );¬
` bytes-=take;¬
` }¬
` ¬
` {// REVISIT - try silencing the fragment¬
` AudioSync_MessageFill(Message, 0);¬
` }¬
` ¬
` } else {¬
` /*¬
` * Data is not quite on time, resample the input¬
` * buffer (up to a 1%) towards the correct values.¬
` */¬

` size_t length = SOS_Message_LengthGet(Message);¬
` size_t inSamples = length / sizeof(SOS_INT32);¬
` size_t outSamples;¬

` if (avgEarly>0) {¬
` size_t maxOutSamples =
`inSamples*MAX_RESAMPLE_PERCENT/100;¬
` outSamples = samples+inSamples;¬
`
`Page 14 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 15/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`613
`614
`615
`616
`617
`…
`618
`…
`619
`620
`621
`622
`623
`624
`625
`626
`627
`628
`629
`630
`631
`632
`633
`634
`635
`636
`637
`638
`639
`640
`641
`642
`643
`644
`645
`646
`647
`648
`649
`650
`651
`652
`653
`654
`655
`
` if (outSamples>maxOutSamples) {¬
` outSamples=maxOutSamples;¬
` }¬
` } else {¬
` size_t minOutSamples =
`inSamples*MIN_RESAMPLE_PERCENT/100;¬
` outSamples = samples>inSamples ? 0 :
`inSamples-samples;¬
` if (outSamples<minOutSamples) {¬
` outSamples=minOutSamples;¬
` }¬
` }¬

` SOS_DEBUGOUT_DETAIL(¬
` "inSamples=%ld, outSamples=%lu\n",¬
` inSamples,¬
` outSamples¬
` );¬
` {¬
` SOS_INT32 *inBuffer = SOS_Mem_Alloc(length);¬
` SOS_INT32 *outBuffer;¬
` SOS_Message_HeadDataPop(¬
` Message,¬
` length,¬
` inBuffer,¬
` NULL¬
` );¬
` outBuffer = AudioSync_Resample16(¬
` inBuffer,¬
` inSamples,¬
` outSamples¬
` );¬
` ¬
` SOS_Message_HeadDataPush(¬
` Message,¬
` outBuffer,¬
` outSamples * sizeof(SOS_INT32),¬
` SOS_Mem_Free¬
` );¬
` SOS_Mem_Free(inBuffer);¬
` }¬
` }¬
` ¬
`#if 0¬
` // USE SILENCE TO FILL THE GAP¬
`
`Page 15 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 16/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`656
`657
`658
`659
`660
`661
`662
`…
`663
`664
`665
`666
`667
`668
`669
`670
`671
`672
`673
`674
`675
`676
`677
`678
`679
`680
`681
`682
`683
`684
`685
`686
`687
`688
`…
`689
`690
`…
`691
`692
`693
`694
`695
`696
`697
`
` // No longer used, but¬
` // REVISIT - might be good to start with silence¬
` // for first couple of packets?¬

` {¬
` void *data = SOS_Mem_Alloc(bytes);¬
`// SOS_Debug_StringPrint("Inserting %ld
`bytes\n",bytes);¬
` SOS_memset(¬
` data,¬
` format.SampleBits>8 ? 0x00 : 0x7F,¬
` bytes¬
` );¬
` SOS_Message_HeadDataPush(¬
` Message,¬
` data,¬
` bytes,¬
` SOS_Mem_Free¬
` );¬
` }¬
`#endif¬
` }¬
` ¬
` Context->AudioContext->Pack(¬
` Context->AudioContext,¬
` Message¬
` );¬
` }¬

` return status;¬
`}¬


`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Bead Definition¬
`--------------------------------------------------------------------------
`---*/¬

`static¬
`SOS_STATUS¬
`AudioSync_MessageHandler(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`
`Page 16 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 17/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`698
`699
`700
`701
`702
`703
`704
`705
`706
`707
`708
`709
`710
`711
`712
`713
`714
`715
`716
`717
`718
`719
`720
`721
`722
`723
`724
`725
`726
`727
`728
`729
`730
`…
`731
`732
`733
`734
`735
`736
`737
`738
`739
`740
`…
`
`{¬
` SOS_STATUS status = SOS_Success;¬
` AUDIOSYNC_CONTEXT *context;¬

` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_MessageHandler\n");¬

` SOS_Path_SessionContextPeek(Path, (void**)&context);¬

` if (!context->ContextReady) {¬
` status = AudioSync_ContextPrepare(context, Path);¬
` if (SOS_SUCCEEDED(status)) {¬
` context->ContextReady = SOS_True;¬
` }¬
` }¬

` if (!context->ContextReady) {¬
` SOS_DEBUGOUT_DETAIL("AudioSync context is not ready");¬
` }¬

` if (context->ContextReady) {¬
` SOS_CLOCK_TICK masterEpoch;¬
` SOS_CLOCK_TICK renderEpoch;¬
` ¬
` if (SOS_SUCCEEDED(context->RenderClock->EpochGet(¬
` context->RenderClock,¬
` &renderEpoch))) {¬
`// SOS_Debug_StringPrint("Now = %lu\n",SOS_Clock_TickGet());¬
`// SOS_Debug_StringPrint("Render epoch = %lu\n",renderEpoch);¬
` ¬
` if (SOS_SUCCEEDED(context->MasterClock->EpochGet(¬
` context->MasterClock,¬
` &masterEpoch))) {¬
`// SOS_Debug_StringPrint("Master epoch =
`%lu\n",masterEpoch);¬

` status = AudioSync_Adjust(¬
` context,¬
` Path,¬
` Message,¬
` masterEpoch,¬
` renderEpoch¬
` );¬
` } else {¬
` SOS_DEBUGOUT_DETAIL("Master clock %p not
`set\n",context->MasterClock->Interface.Object);¬
`
`Page 17 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 18/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`741
`742
`743
`…
`744
`745
`746
`747
`748
`749
`750
`751
`752
`753
`754
`755
`756
`757
`758
`759
`760
`761
`762
`763
`764
`765
`766
`767
`768
`769
`770
`771
`772
`773
`774
`775
`776
`777
`778
`779
`780
`781
`782
`783
`784
`
` }¬
` } else {¬
` SOS_DEBUGOUT_DETAIL("Render clock %p not
`set\n",context->RenderClock->Interface.Object);¬
` }¬
` }¬

` if (context->First) {¬
` if (context->AudioContext) {¬
` context->AudioContext->Unpack(¬
` context->AudioContext,¬
` Message¬
` );¬

` /*¬
` * if it fails to fill the message it¬
` * leaves the message intact, and we return¬
` * the status which causes the message to¬
` * be discarded ultimately (which is fine)¬
` */¬
` status = AudioSync_MessageFill(Message, 0);¬
` ¬
` context->AudioContext->Pack(¬
` context->AudioContext,¬
` Message¬
` );¬
`context->First = SOS_False;¬
` }¬
` }¬

` if (SOS_SUCCEEDED(status)) {¬
` SOS_Path_MessageSend(Path, Message);¬
` } else {¬
` SOS_Message_Destroy(Message);¬
` }¬

` return status;¬
`}¬

`static¬
`SOS_STATUS¬
`AudioSync_PrerollHandler(¬
` SOS_PATH *Path,¬
` SOS_MESSAGE *Message¬
`)¬
`
`Page 18 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 19/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`785
`786
`787
`788
`789
`790
`791
`792
`793
`794
`795
`796
`797
`798
`799
`800
`801
`…
`802
`803
`804
`805
`806
`807
`808
`809
`810
`811
`812
`813
`814
`815
`816
`817
`818
`819
`820
`821
`822
`823
`824
`825
`826
`827
`828
`
`{¬
` SOS_STATUS status = SOS_Success;¬
` AUDIOSYNC_CONTEXT *context;¬

` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_PrerollHandler\n");¬

` SOS_Path_SessionContextPeek(Path, (void**)&context);¬

` if (!context->AudioContext) {¬
` AudioContextGet(¬
` Path,¬
` SOS_AUDIOCONTEXT_NAME,¬
` &context->AudioContext¬
` );¬
` }¬

` SOS_ASSERT_ASSUMPTION(context->AudioContext, "Didn't find audio
`context");¬

` if (context->AudioContext) {¬
` if (context->First) {¬
` SOS_AUDIO_FORMAT format;¬
` SOS_UINT32 delay;¬
` SOS_UINT32 bytes;¬
` void *buffer;¬

` delay = 3000; // ms - REVISIT¬

` SOS_DEBUGOUT_FUNC_TRACE("Adding SILENCE\n");¬
` ¬
` context->AudioContext->Unpack(¬
` context->AudioContext,¬
` Message¬
` );¬

` context->AudioContext->FormatGet(¬
` context->AudioContext,¬
` NULL, /* no message, we've already unpacked it */¬
` &format¬
` );¬
` ¬
` bytes = Scale(delay, format.Frequency, SOS_MSPERSECOND);¬
` buffer = SOS_Mem_Alloc(bytes);¬

` if (buffer) {¬
`
`Page 19 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 20/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`829
`…
`830
`831
`832
`833
`834
`835
`836
`837
`838
`839
`840
`841
`842
`843
`844
`845
`846
`847
`848
`849
`850
`851
`852
`…
`853
`854
`…
`855
`856
`857
`858
`859
`860
`861
`862
`863
`864
`865
`866
`867
`868
`869
`870
`
` unsigned char silence = format.SampleBits <= 8 ? 0x7F :
`0x00;¬
` SOS_memset(buffer, silence, bytes);¬
` SOS_Message_HeadDataPush(¬
` Message,¬
` buffer,¬
` bytes,¬
` SOS_Mem_Free);¬
` }¬

` context->AudioContext->Pack(¬
` context->AudioContext,¬
` Message¬
` );¬

` context->First = SOS_False;¬
` }¬
` }¬

` status = SOS_Path_MessageSend(Path,Message);¬

` return status;¬
`}¬

`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Session Setup¬
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++*/¬

`static¬
`SOS_STATUS¬
`AudioSync_SessionInit(¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` AUDIOSYNC_CONTEXT *context = AudioSync_ContextCreate();¬

` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_SessionInit\n");¬

` if (context) {¬
` SOS_Path_SessionContextPut(Path, context);¬
` } else {¬
` status = SOS_Error;¬
`
`Page 20 of 23
`
`Implicit Exhibit 2017
`Sonos v. Implicit, IPR2018-0766, -0767
`
`

`

`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/audiosync.c
`Page 21/23
`Saved: 10/23/01, 11:53:51 AM
`Printed for: Implicit
`
`871
`872
`873
`874
`875
`876
`877
`878
`879
`880
`881
`882
`883
`884
`885
`886
`887
`888
`889
`890
`891
`892
`893
`894
`895
`896
`…
`897
`898
`…
`899
`900
`901
`902
`903
`904
`905
`906
`907
`908
`909
`910
`911
`912
`913
`
` }¬
` ¬
` return status;¬
`}¬

`static¬
`SOS_STATUS¬
`AudioSync_SessionUninit(¬
` SOS_PATH *Path¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` AUDIOSYNC_CONTEXT *context;¬

` SOS_DEBUGOUT_FUNC_TRACE("AudioSync_SessionUninit\n");¬

` SOS_Path_SessionContextPeek(Path, (void**)&context);¬

` if (context) {¬
` AudioSync_ContextDestroy(context);¬
` }¬

` return status;¬
`}¬

`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`Bead Setup¬
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++*/¬

`static¬
`SOS_STATUS¬
`AudioSync_BeadInit(¬
` SOS_BEAD *Bead,¬
` SOS_REGOBJECT *InitContext¬
`)¬
`{¬
` SOS_STATUS status;¬

` SOS_DEBUGOUT_FUNC_TRAC

This document is available on Docket Alarm but you must sign up to view it.


Or .

Accessing this document will incur an additional charge of $.

After purchase, you can access this document again without charge.

Accept $ Charge
throbber

Still Working On It

This document is taking longer than usual to download. This can happen if we need to contact the court directly to obtain the document and their servers are running slowly.

Give it another minute or two to complete, and then try the refresh button.

throbber

A few More Minutes ... Still Working

It can take up to 5 minutes for us to download a document if the court servers are running slowly.

Thank you for your continued patience.

This document could not be displayed.

We could not find this document within its docket. Please go back to the docket page and check the link. If that does not work, go back to the docket and refresh it to pull the newest information.

Your account does not support viewing this document.

You need a Paid Account to view this document. Click here to change your account type.

Your account does not support viewing this document.

Set your membership status to view this document.

With a Docket Alarm membership, you'll get a whole lot more, including:

  • Up-to-date information for this case.
  • Email alerts whenever there is an update.
  • Full text search for other cases.
  • Get email alerts whenever a new case matches your search.

Become a Member

One Moment Please

The filing “” is large (MB) and is being downloaded.

Please refresh this page in a few minutes to see if the filing has been downloaded. The filing will also be emailed to you when the download completes.

Your document is on its way!

If you do not receive the document in five minutes, contact support at support@docketalarm.com.

Sealed Document

We are unable to display this document, it may be under a court ordered seal.

If you have proper credentials to access the file, you may proceed directly to the court's system using your government issued username and password.


Access Government Site

We are redirecting you
to a mobile optimized page.





Document Unreadable or Corrupt

Refresh this Document
Go to the Docket

We are unable to display this document.

Refresh this Document
Go to the Docket