mirror of
https://github.com/ggerganov/ggwave.git
synced 2026-02-24 16:16:10 +08:00
tests : add test for capture/playback at different sample rates
This commit is contained in:
@@ -181,15 +181,23 @@ public:
|
||||
|
||||
static const Parameters & getDefaultParameters();
|
||||
|
||||
// set Tx data to encode
|
||||
bool init(const std::string & text, const int volume = kDefaultVolume);
|
||||
bool init(const std::string & text, const TxProtocol & txProtocol, const int volume = kDefaultVolume);
|
||||
bool init(int dataSize, const char * dataBuffer, const int volume = kDefaultVolume);
|
||||
bool init(int dataSize, const char * dataBuffer, const TxProtocol & txProtocol, const int volume = kDefaultVolume);
|
||||
|
||||
// expected waveform size of the encoded Tx data
|
||||
uint32_t encodeSize_bytes() const;
|
||||
uint32_t encodeSize_samples() const;
|
||||
|
||||
// encode Tx data into an audio waveform
|
||||
//
|
||||
// returns false if the encoding fails
|
||||
//
|
||||
bool encode(const CBWaveformOut & cbWaveformOut);
|
||||
|
||||
// decode an audio waveform
|
||||
void decode(const CBWaveformInp & cbWaveformInp);
|
||||
|
||||
const bool & hasTxData() const { return m_hasNewTxData; }
|
||||
|
||||
@@ -313,6 +313,11 @@ GGWave::GGWave(const Parameters & parameters) :
|
||||
throw std::runtime_error("Invalid samples per frame");
|
||||
}
|
||||
|
||||
if (m_sampleRateInp < m_sampleRateOut) {
|
||||
fprintf(stderr, "Error: capture sample rate (%d Hz) must be >= playback sample rate (%d Hz)\n", (int) m_sampleRateInp, (int) m_sampleRateOut);
|
||||
throw std::runtime_error("Invalid capture/playback sample rate");
|
||||
}
|
||||
|
||||
init("", getDefaultTxProtocol(), 0);
|
||||
}
|
||||
|
||||
@@ -399,6 +404,7 @@ uint32_t GGWave::encodeSize_samples() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int samplesPerFrameOut = (m_sampleRateOut/m_sampleRateInp)*m_samplesPerFrame;
|
||||
int nECCBytesPerTx = getECCBytesForLength(m_txDataLength);
|
||||
int sendDataLength = m_txDataLength + m_encodedDataOffset;
|
||||
int totalBytes = sendDataLength + nECCBytesPerTx;
|
||||
@@ -406,15 +412,12 @@ uint32_t GGWave::encodeSize_samples() const {
|
||||
|
||||
return (
|
||||
m_nMarkerFrames + m_nPostMarkerFrames + totalDataFrames + m_nMarkerFrames
|
||||
)*m_samplesPerFrame;
|
||||
)*samplesPerFrameOut;
|
||||
}
|
||||
|
||||
bool GGWave::encode(const CBWaveformOut & cbWaveformOut) {
|
||||
int samplesPerFrameOut = (m_sampleRateOut/m_sampleRateInp)*m_samplesPerFrame;
|
||||
if (m_sampleRateOut > m_sampleRateInp) {
|
||||
fprintf(stderr, "Error: capture sample rate (%d Hz) must be <= playback sample rate (%d Hz)\n", (int) m_sampleRateInp, (int) m_sampleRateOut);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_sampleRateOut != m_sampleRateInp) {
|
||||
fprintf(stderr, "Resampling from %d Hz to %d Hz\n", (int) m_sampleRateInp, (int) m_sampleRateOut);
|
||||
}
|
||||
|
||||
@@ -181,6 +181,42 @@ int main() {
|
||||
CHECK_F(instance.init(payload.size(), payload.c_str(), 101));
|
||||
}
|
||||
|
||||
// capture / playback at different sample rates
|
||||
{
|
||||
auto parameters = GGWave::getDefaultParameters();
|
||||
|
||||
std::string payload = "hello";
|
||||
|
||||
// encode
|
||||
{
|
||||
parameters.sampleRateInp = 48000;
|
||||
parameters.sampleRateOut = 12000;
|
||||
GGWave instanceOut(parameters);
|
||||
|
||||
instanceOut.init(payload, 25);
|
||||
auto expectedSize = instanceOut.encodeSize_samples();
|
||||
instanceOut.encode(kCBWaveformOut.at(parameters.sampleFormatOut));
|
||||
printf("Expected = %d, actual = %d\n", expectedSize, nSamples);
|
||||
CHECK(expectedSize == nSamples);
|
||||
convertHelper(parameters.sampleFormatOut, parameters.sampleFormatInp);
|
||||
}
|
||||
|
||||
// decode
|
||||
{
|
||||
parameters.samplesPerFrame *= float(parameters.sampleRateOut)/parameters.sampleRateInp;
|
||||
parameters.sampleRateInp = parameters.sampleRateOut;
|
||||
GGWave instanceInp(parameters);
|
||||
|
||||
instanceInp.decode(kCBWaveformInp.at(parameters.sampleFormatInp));
|
||||
|
||||
GGWave::TxRxData result;
|
||||
CHECK(instanceInp.takeRxData(result) == (int) payload.size());
|
||||
for (int i = 0; i < (int) payload.size(); ++i) {
|
||||
CHECK(payload[i] == result[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto & txProtocol : GGWave::getTxProtocols()) {
|
||||
for (const auto & formatOut : kFormats) {
|
||||
for (const auto & formatInp : kFormats) {
|
||||
@@ -201,12 +237,10 @@ int main() {
|
||||
convertHelper(formatOut, formatInp);
|
||||
instance.decode(kCBWaveformInp.at(formatInp));
|
||||
|
||||
{
|
||||
GGWave::TxRxData result;
|
||||
CHECK(instance.takeRxData(result) == (int) payload.size());
|
||||
for (int i = 0; i < (int) payload.size(); ++i) {
|
||||
CHECK(payload[i] == result[i]);
|
||||
}
|
||||
GGWave::TxRxData result;
|
||||
CHECK(instance.takeRxData(result) == (int) payload.size());
|
||||
for (int i = 0; i < (int) payload.size(); ++i) {
|
||||
CHECK(payload[i] == result[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user