Skip to content

Commit

Permalink
Update C API to include timestamps for offline ASR
Browse files Browse the repository at this point in the history
  • Loading branch information
csukuangfj committed Sep 14, 2023
1 parent b6d8057 commit 42f042d
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 14 deletions.
11 changes: 11 additions & 0 deletions sherpa-onnx/c-api/c-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,22 @@ SherpaOnnxOfflineRecognizerResult *GetOfflineStreamResult(
std::copy(text.begin(), text.end(), const_cast<char *>(r->text));
const_cast<char *>(r->text)[text.size()] = 0;

if (!result.timestamps.empty()) {
r->timestamps = new float[result.timestamps.size()];
std::copy(result.timestamps.begin(), result.timestamps.end(),
r->timestamps);
r->count = result.timestamps.size();
} else {
r->timestamps = nullptr;
r->count = 0;
}

return r;
}

void DestroyOfflineRecognizerResult(
const SherpaOnnxOfflineRecognizerResult *r) {
delete[] r->text;
delete[] r->timestamps;
delete r;
}
8 changes: 8 additions & 0 deletions sherpa-onnx/c-api/c-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,14 @@ SHERPA_ONNX_API void DecodeMultipleOfflineStreams(

SHERPA_ONNX_API typedef struct SherpaOnnxOfflineRecognizerResult {
const char *text;

// Pointer to continuous memory which holds timestamps
//
// It is NULL if the model does not support timestamps
float *timestamps;

// number of entries in timestamps
int32_t count;
// TODO(fangjun): Add more fields
} SherpaOnnxOfflineRecognizerResult;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "sherpa-onnx/csrc/offline-paraformer-greedy-search-decoder.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "sherpa-onnx/csrc/macros.h"
Expand Down
1 change: 1 addition & 0 deletions sherpa-onnx/csrc/offline-paraformer-model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <algorithm>
#include <string>
#include <utility>

#include "sherpa-onnx/csrc/macros.h"
#include "sherpa-onnx/csrc/onnx-utils.h"
Expand Down
17 changes: 17 additions & 0 deletions swift-api-examples/SherpaOnnx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,23 @@ class SherpaOnnxOfflineRecongitionResult {
return String(cString: result.pointee.text)
}

var count: Int32 {
return result.pointee.count
}

var timestamps: [Float] {
if let p = result.pointee.timestamps {
var timestamps: [Float] = []
for index in 0..<count {
timestamps.append(p[Int(index)])
}
return timestamps
} else {
let timestamps: [Float] = []
return timestamps
}
}

init(result: UnsafePointer<SherpaOnnxOfflineRecognizerResult>!) {
self.result = result
}
Expand Down
56 changes: 42 additions & 14 deletions swift-api-examples/decode-file-non-streaming.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,45 @@ extension AVAudioPCMBuffer {
}

func run() {
let encoder = "./sherpa-onnx-whisper-tiny.en/tiny.en-encoder.int8.onnx"
let decoder = "./sherpa-onnx-whisper-tiny.en/tiny.en-decoder.int8.onnx"
let tokens = "./sherpa-onnx-whisper-tiny.en/tiny.en-tokens.txt"

let whisperConfig = sherpaOnnxOfflineWhisperModelConfig(
encoder: encoder,
decoder: decoder
)
var recognizer: SherpaOnnxOfflineRecognizer
var modelConfig: SherpaOnnxOfflineModelConfig
var modelType = "whisper"
// modelType = "paraformer"

let modelConfig = sherpaOnnxOfflineModelConfig(
tokens: tokens,
whisper: whisperConfig,
debug: 0,
modelType: "whisper"
)
if modelType == "whisper" {
let encoder = "./sherpa-onnx-whisper-tiny.en/tiny.en-encoder.int8.onnx"
let decoder = "./sherpa-onnx-whisper-tiny.en/tiny.en-decoder.int8.onnx"
let tokens = "./sherpa-onnx-whisper-tiny.en/tiny.en-tokens.txt"

let whisperConfig = sherpaOnnxOfflineWhisperModelConfig(
encoder: encoder,
decoder: decoder
)

modelConfig = sherpaOnnxOfflineModelConfig(
tokens: tokens,
whisper: whisperConfig,
debug: 0,
modelType: "whisper"
)
} else if modelType == "paraformer" {
let model = "./sherpa-onnx-paraformer-zh-2023-09-14/model.int8.onnx"
let tokens = "./sherpa-onnx-paraformer-zh-2023-09-14/tokens.txt"
let paraformerConfig = sherpaOnnxOfflineParaformerModelConfig(
model: model
)

modelConfig = sherpaOnnxOfflineModelConfig(
tokens: tokens,
paraformer: paraformerConfig,
debug: 0,
modelType: "paraformer"
)
} else {
print("Please specify a supported modelType \(modelType)")
return
}

let featConfig = sherpaOnnxFeatureConfig(
sampleRate: 16000,
Expand All @@ -38,7 +62,7 @@ func run() {
modelConfig: modelConfig
)

let recognizer = SherpaOnnxOfflineRecognizer(config: &config)
recognizer = SherpaOnnxOfflineRecognizer(config: &config)

let filePath = "./sherpa-onnx-whisper-tiny.en/test_wavs/0.wav"
let fileURL: NSURL = NSURL(fileURLWithPath: filePath)
Expand All @@ -55,6 +79,10 @@ func run() {
let array: [Float]! = audioFileBuffer?.array()
let result = recognizer.decode(samples: array, sampleRate: Int(audioFormat.sampleRate))
print("\nresult is:\n\(result.text)")
if result.timestamps.count != 0 {
print("\ntimestamps is:\n\(result.timestamps)")
}

}

@main
Expand Down

0 comments on commit 42f042d

Please sign in to comment.