You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sometimes, there are already speakers in the database that may have the same ID.
78
+
```swift
79
+
let alice =Speaker(id: "alice", name: "Alice", currentEmbedding: aliceEmbedding)
80
+
let bob =Speaker(id: "bob", name: "Bob", currentEmbedding: bobEmbedding)
81
+
speakerManager.initializeKnownSpeakers([alice, bob], mode: .overwrite, preserveIfPermanent: false) // replace any speakers with ID "alice" or "bob" with the new speakers, even if the old ones were marked as permanent.
82
+
```
83
+
84
+
> The `mode` argument dictates how to handle redundant speakers. It is of type `SpeakerInitializationMode`, and can take on one of four values:
85
+
> -`.reset`: reset the speaker database and add the new speakers
86
+
> -`.merge`: merge new speakers whose IDs match with existing ones
87
+
> -`.overwrite`: overwrite existing speakers with the same IDs as the new ones
88
+
> -`.skip`: skip adding speakers whose IDs match existing ones
89
+
>
90
+
> The `preserveIfPermanent` argument determines whether existing speakers marked as permanent should be preserved (i.e., not overwritten or merged). It is `true` by default.
91
+
76
92
**Use case:** When you have pre-recorded voice samples of known speakers and want to recognize them by name instead of numeric IDs.
- If speaker ID exists: updates the existing speaker's data
99
116
- If speaker ID is new: inserts as a new speaker
100
117
- Maintains ID uniqueness and tracks numeric IDs for auto-increment
118
+
- If `isPermanent` is true, then the new speaker or the existing speaker will become permanent. This means that the speaker will not be merged or removed without an override.
119
+
120
+
#### mergeSpeaker
121
+
```swift
122
+
// merge speaker 1 into "alice"
123
+
speakerManager.mergeSpeaker("1", into: "alice")
124
+
125
+
// merge speaker 2 into speaker 3 under the name "bob", regardless of whether speaker 2 is permanent.
// Returns an array of IDs corresponding to speakers that meet the predicate.
229
+
```
230
+
231
+
> Note: the predicate should take in a `Speaker` object and return a `Bool`.
232
+
233
+
#### findMergeablePairs
234
+
Find all pairs of speakers that might be the same person. Specifically, find the pairs of speakers such that the cosine distance between them is less than the `speakerThreshold`.
235
+
236
+
Returns a list of pairs of speaker IDs.
237
+
238
+
```swift
239
+
let pairs = speakerManager.findMergeablePairs(
240
+
speakerThreshold: 0.6, // optional
241
+
excludeIfBothPermanent: true// optional
242
+
)
243
+
244
+
for pair in pairs {
245
+
print("Merge Speaker \(pair.speakerToMerge) into Speaker \(pair.destination)")
246
+
}
247
+
```
248
+
104
249
#### getSpeaker
105
250
Get a specific speaker by ID.
106
251
@@ -118,6 +263,22 @@ let allSpeakers = speakerManager.getAllSpeakers()
118
263
// Returns: [String: Speaker] - dictionary keyed by speaker ID
119
264
```
120
265
266
+
#### getSpeakerList
267
+
Get all speakers in the database as an array of speakers (for testing/debugging)
268
+
```swift
269
+
let allSpeakers = speakerManager.getSpeakerList()
270
+
// Returns: [Speaker] - Array of speakers
271
+
```
272
+
273
+
#### hasSpeaker
274
+
Check if the speaker database has a speaker with a given ID.
275
+
276
+
```swift
277
+
if speakerManager.hasSpeaker("alice") {
278
+
print("Alice was found in the database")
279
+
}
280
+
```
281
+
121
282
#### speakerCount
122
283
Get the total number of tracked speakers.
123
284
@@ -140,13 +301,16 @@ Clear all speakers from the database.
140
301
141
302
```swift
142
303
speakerManager.reset()
304
+
speakerManager.reset(keepIfPermanent: true) // remove all non-permanent speakers from the database
143
305
```
144
306
145
307
Useful for:
146
308
- Starting a new session
147
309
- Freeing memory between recordings
148
310
- Resetting speaker tracking
149
311
312
+
313
+
150
314
## Speaker Enrollment
151
315
152
316
The `Speaker` class includes a `name` field for speaker enrollment workflows:
@@ -237,6 +401,7 @@ public final class Speaker: Identifiable, Codable {
237
401
publicvar updatedAt: Date // Last update timestamp
|`assignSpeaker(_:speechDuration:confidence:)`|`Speaker?`| Assign/create speaker from embedding |
550
-
|`initializeKnownSpeakers(_:)`|`Void`| Pre-load known speaker profiles |
715
+
|`initializeKnownSpeakers(_:mode:preserveIfPermanent:)`|`Void`| Pre-load known speaker profiles |
716
+
|`findSpeaker(with:speakerThreshold:)`|`(id: String?, distance: Float)`| Find speaker that matches an embedding |
717
+
|`findMatchingSpeakers(with:speakerThreshold:)`|`[(id: String, distance: Float)]`| Find all speakers that match an embedding |
718
+
| `findSpeakers(where:)` | `[String]` | Find all speakers that meet a certain predicate
719
+
|`findMergeablePairs(speakerThreshold:excludeIfBothPermanent:)`|`[(speakerToMerge: String, destination: String)]`| Find all pairs of very similar speakers |
720
+
|`removeSpeaker(_:keepIfPermanent:)`|`Void`| Remove a speaker from the database |
721
+
|`removeSpeakersInactive(since:keepIfPermanent:)`|`Void`| Remove speakers inactive since a given date |
722
+
|`removeSpeakersInactive(for:keepIfPermanent:)`|`Void`| Remove speakers inactive for a given duration |
723
+
|`removeSpeakers(where:)`|`Void`| Remove speakers that satisfy a given predicate |
724
+
|`removeSpeakers(where:keepIfPermanent:)`|`Void`| Remove speakers that satisfy a given predicate |
725
+
|`mergeSpeaker(_:into:mergedName:stopIfPermanent:)`|`Void`| Merge a speaker into another one |
551
726
|`upsertSpeaker(_:)`|`Void`| Update or insert speaker (from object) |
552
727
|`upsertSpeaker(id:currentEmbedding:duration:...)`|`Void`| Update or insert speaker (from params) |
553
728
|`getSpeaker(for:)`|`Speaker?`| Get speaker by ID |
554
729
|`getAllSpeakers()`|`[String: Speaker]`| Get all speakers (debugging) |
555
-
|`reset()`|`Void`| Clear speaker database |
556
-
|`reassignSegment(segmentId:from:to:)`|`Bool`| Move segment between speakers |
730
+
|`getSpeakerList()`|`[Speaker]`| Get array of all speakers (debugging) |
731
+
|`hasSpeaker(_:)`|`Bool`| Check if database has a speaker with a given ID |
0 commit comments