-
The
CompareVoiceprintsendpoint allows the user to compare pre-extracted voiceprints and get similarity scores and match results without needing to send audio data. -
This is useful in cases where the user wants to compare a given voiceprint against a large number of other voiceprints, and sending audio data for each comparison would be inefficient. The client can enroll the voiceprint once using the
StreamingEnrollmethod, and then use this method to compare it against a large number of other voiceprints in batches. -
The following example shows how to compare pre-extracted voiceprints using VoiceBio’s
CompareVoiceprintsAPI, without streaming audio. The voiceprints can be loaded from files on disk or obtained from previous enrollment sessions.
Info
Voiceprints provided inCompareVoiceprints requests must be generated using the
same or compatible model via StreamingEnroll.
import grpc
import cobaltspeech.voicebio.v1.voicebio_pb2_grpc as stub
import cobaltspeech.voicebio.v1.voicebio_pb2 as voicebio
serverAddress = "localhost:2727"
# Using a channel without TLS enabled.
channel = grpc.insecure_channel(serverAddress)
client = stub.VoiceBioServiceStub(channel)
# Get server version.
versionResp = client.Version(voicebio.VersionRequest())
print(versionResp)
# Get list of models on the server.
modelResp = client.ListModels(voicebio.ListModelsRequest())
print("Models:")
for model in modelResp.models:
print(model)
# Select a model ID from the list above. Going with the first model
# in this example. The model ID should be the same as the one used to
# generate the voiceprints being compared.
modelID = modelResp.models[0].id
# Loading reference voiceprints.
reference_voiceprints = []
for p in ["user1.bin", "user2.bin", "user3.bin"]:
with open(p, 'r') as f:
reference_voiceprints.append(voicebio.Voiceprint(data=f.read().strip()))
# Load the target voiceprint that we want to compare against the reference voiceprints.
with open("unknown.bin", 'r') as f:
target_voiceprint = voicebio.Voiceprint(data=f.read().strip())
# Set the comparison config.
req = voicebio.CompareVoiceprintsRequest(
model_id=modelID,
target_voiceprint=target_voiceprint,
reference_voiceprints=reference_voiceprints,
)
# Compare voiceprints.
result = client.CompareVoiceprints(req)
# Server returns the index of the voiceprint that matches the best, a similarity
# score for each voiceprint along with whether the score exceeded the server-configured
# threshold for being a match.
#
# If none of the voiceprints were a good match, the best match index will be negative.
matched = "❌ No Match found"
if result.best_match_index >= 0:
best_score = result.voiceprint_comparison_results[result.best_match_index].similarity_score
matched = f"✅ Match found: Index: {result.best_match_index}, Score: {best_score:1.3f}"
print(f"\nComparison Result:\n")
print("Scores:")
for i, r in enumerate(result.voiceprint_comparison_results):
print(f"Index: {i}, Score: {r.similarity_score:1.3f}, IsMatch: {r.is_match}")
print(f"\n{matched}")package main
import (
"context"
"fmt"
"os"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
voicebio "github.com/cobaltspeech/go-genproto/cobaltspeech/voicebio/v1"
)
func main() {
const (
serverAddress = "localhost:2727"
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()), // Using a channel without TLS enabled.
grpc.WithBlock(),
grpc.WithReturnConnectionError(),
grpc.FailOnNonTempDialError(true),
}
conn, err := grpc.DialContext(ctx, serverAddress, opts...)
if err != nil {
fmt.Printf("failed to dial gRPC connection: %v\n", err)
os.Exit(1)
}
client := voicebio.NewVoiceBioServiceClient(conn)
// Get server version.
versionResp, err := client.Version(ctx, &voicebio.VersionRequest{})
if err != nil {
fmt.Printf("failed to get server version: %v\n", err)
os.Exit(1)
}
fmt.Printf("%v\n", versionResp)
// Get list model of models on the server.
modelResp, err := client.ListModels(ctx, &voicebio.ListModelsRequest{})
if err != nil {
fmt.Printf("failed to get model list: %v\n", err)
os.Exit(1)
}
fmt.Println("Models:")
for _, m := range modelResp.Models {
fmt.Println(m)
}
fmt.Println()
// Reading voiceprint data.
reference_voiceprints := make([]*voicebio.Voiceprint, 0)
for i, p := range []string{"user1.bin", "user2.bin", "user3.bin"} {
data, err := os.ReadFile(p)
if err != nil {
fmt.Printf("\nfailed to read voiceprint[%d] data: %v\n", i, err)
os.Exit(1)
}
reference_voiceprints = append(reference_voiceprints, &voicebio.Voiceprint{Data: string(data)})
}
// Load the target voiceprint that we want to compare against the reference voiceprints.
data, err := os.ReadFile("unknown.bin")
if err != nil {
fmt.Printf("failed to read target voiceprint data: %v\n", err)
os.Exit(1)
}
target_voiceprint := &voicebio.Voiceprint{Data: string(data)}
// Selecting the first model. The model ID should be the same as the one used to generate the
// voiceprints being compared.
req := &voicebio.CompareVoiceprintsRequest{
ModelId: modelResp.Models[0].Id,
TargetVoiceprint: target_voiceprint,
ReferenceVoiceprints: reference_voiceprints,
}
// Compare voiceprints.
result, err := client.CompareVoiceprints(ctx, req)
if err != nil {
fmt.Printf("failed to compare voiceprints: %v\n", err)
os.Exit(1)
}
// Server returns the index of the voiceprint that matches the best, a similarity
// score for each voiceprint along with whether the score exceeded the server-configured
// threshold for being a match.
//
// If none of the voiceprints were a good match, the best match index will be negative.
matched := "❌ No Match found"
if result.BestMatchIndex >= 0 {
bestScore := result.VoiceprintComparisonResults[result.BestMatchIndex].SimilarityScore
matched = fmt.Sprintf("✅ Match found: Index: %d, Score: %1.3f", result.BestMatchIndex, bestScore)
}
fmt.Printf("\n Comparison Result:\n")
fmt.Printf("Scores:\n")
for i, r := range result.VoiceprintComparisonResults {
fmt.Printf("Index: %d, Score: %1.3f, IsMatch: %v\n", i, r.SimilarityScore, r.IsMatch)
}
fmt.Printf("\n%s\n", matched)
}