-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First working version of offline greedy search (#2)
- Loading branch information
1 parent
db5c5ac
commit 6b7180a
Showing
6 changed files
with
409 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,15 @@ | ||
include_directories(${CMAKE_SOURCE_DIR}) | ||
|
||
add_executable(online-fbank-test online-fbank-test.cc) | ||
target_link_libraries(online-fbank-test kaldi-native-fbank-core) | ||
|
||
add_executable(sherpa-ncnn | ||
sherpa-ncnn.cc | ||
symbol-table.cc | ||
wave-reader.cc | ||
) | ||
|
||
target_link_libraries(sherpa-ncnn | ||
ncnn | ||
kaldi-native-fbank-core | ||
) | ||
target_link_libraries(sherpa-ncnn ncnn) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* Copyright 2022 Xiaomi Corporation (authors: Fangjun Kuang) | ||
* | ||
* See LICENSE for clarification regarding multiple authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include "sherpa-ncnn/csrc/symbol-table.h" | ||
|
||
#include <cassert> | ||
#include <fstream> | ||
#include <sstream> | ||
|
||
namespace sherpa_ncnn { | ||
|
||
SymbolTable::SymbolTable(const std::string &filename) { | ||
std::ifstream is(filename); | ||
std::string sym; | ||
int32_t id; | ||
while (is >> sym >> id) { | ||
if (sym.size() >= 3) { | ||
// For BPE-based models, we replace ▁ with a space | ||
// Unicode 9601, hex 0x2581, utf8 0xe29681 | ||
const uint8_t *p = reinterpret_cast<const uint8_t *>(sym.c_str()); | ||
if (p[0] == 0xe2 && p[1] == 0x96 && p[2] == 0x81) { | ||
sym = sym.replace(0, 3, " "); | ||
} | ||
} | ||
|
||
assert(!sym.empty()); | ||
assert(sym2id_.count(sym) == 0); | ||
assert(id2sym_.count(id) == 0); | ||
|
||
sym2id_.insert({sym, id}); | ||
id2sym_.insert({id, sym}); | ||
} | ||
assert(is.eof()); | ||
} | ||
|
||
std::string SymbolTable::ToString() const { | ||
std::ostringstream os; | ||
char sep = ' '; | ||
for (const auto &p : sym2id_) { | ||
os << p.first << sep << p.second << "\n"; | ||
} | ||
return os.str(); | ||
} | ||
|
||
const std::string &SymbolTable::operator[](int32_t id) const { | ||
return id2sym_.at(id); | ||
} | ||
|
||
int32_t SymbolTable::operator[](const std::string &sym) const { | ||
return sym2id_.at(sym); | ||
} | ||
|
||
bool SymbolTable::contains(int32_t id) const { return id2sym_.count(id) != 0; } | ||
|
||
bool SymbolTable::contains(const std::string &sym) const { | ||
return sym2id_.count(sym) != 0; | ||
} | ||
|
||
std::ostream &operator<<(std::ostream &os, const SymbolTable &symbol_table) { | ||
return os << symbol_table.ToString(); | ||
} | ||
|
||
} // namespace sherpa_ncnn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* Copyright 2022 Xiaomi Corporation (authors: Fangjun Kuang) | ||
* | ||
* See LICENSE for clarification regarding multiple authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef SHERPA_NCNN_CSRC_SYMBOL_TABLE_H_ | ||
#define SHERPA_NCNN_CSRC_SYMBOL_TABLE_H_ | ||
|
||
#include <string> | ||
#include <unordered_map> | ||
|
||
namespace sherpa_ncnn { | ||
|
||
/// It manages mapping between symbols and integer IDs. | ||
class SymbolTable { | ||
public: | ||
SymbolTable() = default; | ||
/// Construct a symbol table from a file. | ||
/// Each line in the file contains two fields: | ||
/// | ||
/// sym ID | ||
/// | ||
/// Fields are separated by space(s). | ||
explicit SymbolTable(const std::string &filename); | ||
|
||
/// Return a string representation of this symbol table | ||
std::string ToString() const; | ||
|
||
/// Return the symbol corresponding to the given ID. | ||
const std::string &operator[](int32_t id) const; | ||
/// Return the ID corresponding to the given symbol. | ||
int32_t operator[](const std::string &sym) const; | ||
|
||
/// Return true if there is a symbol with the given ID. | ||
bool contains(int32_t id) const; | ||
|
||
/// Return true if there is a given symbol in the symbol table. | ||
bool contains(const std::string &sym) const; | ||
|
||
private: | ||
std::unordered_map<std::string, int32_t> sym2id_; | ||
std::unordered_map<int32_t, std::string> id2sym_; | ||
}; | ||
|
||
std::ostream &operator<<(std::ostream &os, const SymbolTable &symbol_table); | ||
|
||
} // namespace sherpa_ncnn | ||
|
||
#endif // SHERPA_NCNN_CSRC_SYMBOL_TABLE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/** | ||
* Copyright 2021 Xiaomi Corporation (authors: Fangjun Kuang) | ||
* | ||
* See LICENSE for clarification regarding multiple authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <cassert> | ||
#include <fstream> | ||
#include <iostream> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "sherpa-ncnn/csrc/wave-reader.h" | ||
|
||
namespace sherpa_ncnn { | ||
namespace { | ||
// see http://soundfile.sapp.org/doc/WaveFormat/ | ||
// | ||
// Note: We assume little endian here | ||
// TODO(fangjun): Support big endian | ||
struct WaveHeader { | ||
void Validate() const { | ||
// F F I R | ||
assert(chunk_id == 0x46464952); | ||
assert(chunk_size == 36 + subchunk2_size); | ||
// E V A W | ||
assert(format == 0x45564157); | ||
assert(subchunk1_id == 0x20746d66); | ||
assert(subchunk1_size == 16); // 16 for PCM | ||
assert(audio_format == 1); // 1 for PCM | ||
assert(num_channels == 1); // we support only single channel for now | ||
assert(byte_rate == sample_rate * num_channels * bits_per_sample / 8); | ||
assert(block_align == num_channels * bits_per_sample / 8); | ||
assert(bits_per_sample == 16); // we support only 16 bits per sample | ||
} | ||
|
||
int32_t chunk_id; | ||
int32_t chunk_size; | ||
int32_t format; | ||
int32_t subchunk1_id; | ||
int32_t subchunk1_size; | ||
int16_t audio_format; | ||
int16_t num_channels; | ||
int32_t sample_rate; | ||
int32_t byte_rate; | ||
int16_t block_align; | ||
int16_t bits_per_sample; | ||
int32_t subchunk2_id; | ||
int32_t subchunk2_size; | ||
}; | ||
static_assert(sizeof(WaveHeader) == 44, ""); | ||
|
||
// Read a wave file of mono-channel. | ||
// Return its samples normalized to the range [-1, 1). | ||
std::vector<float> ReadWaveImpl(std::istream &is, float *sample_rate) { | ||
WaveHeader header; | ||
is.read(reinterpret_cast<char *>(&header), sizeof(header)); | ||
assert((bool)is); | ||
|
||
header.Validate(); | ||
|
||
*sample_rate = header.sample_rate; | ||
|
||
// header.subchunk2_size contains the number of bytes in the data. | ||
// As we assume each sample contains two bytes, so it is divided by 2 here | ||
std::vector<int16_t> samples(header.subchunk2_size / 2); | ||
|
||
is.read(reinterpret_cast<char *>(samples.data()), header.subchunk2_size); | ||
|
||
assert((bool)is); | ||
|
||
std::vector<float> ans(samples.size()); | ||
for (int32_t i = 0; i != ans.size(); ++i) { | ||
ans[i] = samples[i] / 32768.; | ||
} | ||
|
||
return ans; | ||
} | ||
|
||
} // namespace | ||
|
||
std::vector<float> ReadWave(const std::string &filename, | ||
float expected_sample_rate) { | ||
std::ifstream is(filename, std::ifstream::binary); | ||
float sample_rate; | ||
auto samples = ReadWaveImpl(is, &sample_rate); | ||
if (expected_sample_rate != sample_rate) { | ||
std::cerr << "Expected sample rate: " << expected_sample_rate | ||
<< ". Given: " << sample_rate << ".\n"; | ||
exit(-1); | ||
} | ||
return samples; | ||
} | ||
|
||
} // namespace sherpa_ncnn |
Oops, something went wrong.