mirror of
https://github.com/ggerganov/ggwave.git
synced 2026-03-31 18:06:51 +08:00
ggwave : switch to floating point sampling rate
This commit is contained in:
@@ -45,7 +45,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
int getSampleRate() { return g_ggWave->getSampleRateInp(); }
|
||||
float getSampleRate() { return g_ggWave->getSampleRateInp(); }
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE
|
||||
int getFramesToRecord() { return g_ggWave->getFramesToRecord(); }
|
||||
@@ -79,7 +79,7 @@ bool GGWave_init(
|
||||
const int playbackId,
|
||||
const int captureId,
|
||||
const int payloadLength,
|
||||
const int sampleRateOffset) {
|
||||
const float sampleRateOffset) {
|
||||
|
||||
if (g_devIdInp && g_devIdOut) {
|
||||
return false;
|
||||
@@ -217,8 +217,8 @@ bool GGWave_init(
|
||||
|
||||
g_ggWave = new GGWave({
|
||||
payloadLength,
|
||||
g_obtainedSpecInp.freq,
|
||||
g_obtainedSpecOut.freq,
|
||||
(float) g_obtainedSpecInp.freq,
|
||||
(float) g_obtainedSpecOut.freq,
|
||||
GGWave::kDefaultSamplesPerFrame,
|
||||
GGWave::kDefaultSoundMarkerThreshold,
|
||||
sampleFormatInp,
|
||||
|
||||
@@ -7,7 +7,7 @@ class GGWave;
|
||||
// GGWave helpers
|
||||
|
||||
void GGWave_setDefaultCaptureDeviceName(std::string name);
|
||||
bool GGWave_init(const int playbackId, const int captureId, const int payloadLength = -1, const int sampleRateOffset = 0);
|
||||
bool GGWave_init(const int playbackId, const int captureId, const int payloadLength = -1, const float sampleRateOffset = 0);
|
||||
GGWave *& GGWave_instance();
|
||||
bool GGWave_mainLoop();
|
||||
bool GGWave_deinit();
|
||||
|
||||
@@ -5,7 +5,7 @@ Output a generated waveform to an uncompressed WAV file.
|
||||
```
|
||||
Usage: ./bin/ggwave-to-file [-vN] [-sN] [-pN]
|
||||
-vN - output volume, N in (0, 100], (default: 50)
|
||||
-sN - output sample rate, N in [1024, 48000], (default: 48000)
|
||||
-sN - output sample rate, N in [6000, 96000], (default: 48000)
|
||||
-pN - select the transmission protocol (default: 1)
|
||||
|
||||
Available protocols:
|
||||
@@ -59,11 +59,11 @@ curl -sS 'https://ggwave-to-file.ggerganov.com/?m=Hello world!&p=4' --output hel
|
||||
### browser
|
||||
|
||||
- Audible example
|
||||
|
||||
|
||||
https://ggwave-to-file.ggerganov.com/?m=Hello%20world%21
|
||||
|
||||
- Ultrasound example
|
||||
|
||||
|
||||
https://ggwave-to-file.ggerganov.com/?m=Hello%20world%21&p=4
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ curl -sS 'https://ggwave-to-file.ggerganov.com/?m=Hello world!&p=4' --output hel
|
||||
```python
|
||||
import requests
|
||||
|
||||
def ggwave(message: str, protocolId: int = 1, sampleRate: int = 48000, volume: int = 50):
|
||||
def ggwave(message: str, protocolId: int = 1, sampleRate: float = 48000, volume: int = 50):
|
||||
|
||||
url = 'https://ggwave-to-file.ggerganov.com/'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import sys
|
||||
import requests
|
||||
|
||||
def ggwave(message: str, protocolId: int = 1, sampleRate: int = 48000, volume: int = 50):
|
||||
def ggwave(message: str, protocolId: int = 1, sampleRate: float = 48000, volume: int = 50):
|
||||
|
||||
url = 'https://ggwave-to-file.ggerganov.com/'
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
int volume = argm["v"].empty() ? 50 : std::stoi(argm["v"]);
|
||||
int sampleRateOut = argm["s"].empty() ? GGWave::kBaseSampleRate : std::stoi(argm["s"]);
|
||||
float sampleRateOut = argm["s"].empty() ? GGWave::kBaseSampleRate : std::stof(argm["s"]);
|
||||
int protocolId = argm["p"].empty() ? 1 : std::stoi(argm["p"]);
|
||||
|
||||
if (volume <= 0 || volume > 100) {
|
||||
@@ -42,8 +42,8 @@ int main(int argc, char** argv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sampleRateOut < 1024 || sampleRateOut > GGWave::kBaseSampleRate) {
|
||||
fprintf(stderr, "Invalid sample rate\n");
|
||||
if (sampleRateOut < GGWave::kSampleRateMin || sampleRateOut > GGWave::kSampleRateMax) {
|
||||
fprintf(stderr, "Invalid sample rate: %g\n", sampleRateOut);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ int g_freqDataHead = 0;
|
||||
int g_freqDataSize = 0;
|
||||
std::vector<FreqData> g_freqData;
|
||||
|
||||
int g_sampleRateOffset = 0;
|
||||
float g_sampleRateOffset = 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -84,8 +84,6 @@ bool GGWave_init(
|
||||
}
|
||||
}
|
||||
|
||||
bool reinit = false;
|
||||
|
||||
if (g_devIdOut == 0) {
|
||||
printf("Initializing playback ...\n");
|
||||
|
||||
@@ -127,8 +125,6 @@ bool GGWave_init(
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
reinit = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,33 +154,9 @@ bool GGWave_init(
|
||||
printf(" - Format: %d (required: %d)\n", g_obtainedSpecInp.format, captureSpec.format);
|
||||
printf(" - Channels: %d (required: %d)\n", g_obtainedSpecInp.channels, captureSpec.channels);
|
||||
printf(" - Samples per frame: %d\n", g_obtainedSpecInp.samples);
|
||||
|
||||
reinit = true;
|
||||
}
|
||||
}
|
||||
|
||||
GGWave::SampleFormat sampleFormatInp = GGWAVE_SAMPLE_FORMAT_UNDEFINED;
|
||||
GGWave::SampleFormat sampleFormatOut = GGWAVE_SAMPLE_FORMAT_UNDEFINED;
|
||||
|
||||
switch (g_obtainedSpecInp.format) {
|
||||
case AUDIO_U8: sampleFormatInp = GGWAVE_SAMPLE_FORMAT_U8; break;
|
||||
case AUDIO_S8: sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I8; break;
|
||||
case AUDIO_U16SYS: sampleFormatInp = GGWAVE_SAMPLE_FORMAT_U16; break;
|
||||
case AUDIO_S16SYS: sampleFormatInp = GGWAVE_SAMPLE_FORMAT_I16; break;
|
||||
case AUDIO_S32SYS: sampleFormatInp = GGWAVE_SAMPLE_FORMAT_F32; break;
|
||||
case AUDIO_F32SYS: sampleFormatInp = GGWAVE_SAMPLE_FORMAT_F32; break;
|
||||
}
|
||||
|
||||
switch (g_obtainedSpecOut.format) {
|
||||
case AUDIO_U8: sampleFormatOut = GGWAVE_SAMPLE_FORMAT_U8; break;
|
||||
case AUDIO_S8: sampleFormatOut = GGWAVE_SAMPLE_FORMAT_I8; break;
|
||||
case AUDIO_U16SYS: sampleFormatOut = GGWAVE_SAMPLE_FORMAT_U16; break;
|
||||
case AUDIO_S16SYS: sampleFormatOut = GGWAVE_SAMPLE_FORMAT_I16; break;
|
||||
case AUDIO_S32SYS: sampleFormatOut = GGWAVE_SAMPLE_FORMAT_F32; break;
|
||||
case AUDIO_F32SYS: sampleFormatOut = GGWAVE_SAMPLE_FORMAT_F32; break;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -477,7 +449,7 @@ int main(int argc, char** argv) {
|
||||
ImGui::DragInt("Min", &g_binMin, 1, 0, g_binMax - 1);
|
||||
ImGui::DragInt("Max", &g_binMax, 1, g_binMin + 1, g_nSamplesPerFrame/2);
|
||||
ImGui::DragFloat("Scale", &g_scale, 1.0f, 1.0f, 1000.0f);
|
||||
if (ImGui::SliderInt("Offset", &g_sampleRateOffset, -2048, 2048)) {
|
||||
if (ImGui::SliderFloat("Offset", &g_sampleRateOffset, -2048, 2048)) {
|
||||
GGWave_deinit();
|
||||
GGWave_init(0, 0);
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ struct Input {
|
||||
Message message;
|
||||
|
||||
// reinit
|
||||
int sampleRateOffset = 0;
|
||||
float sampleRateOffset = 0;
|
||||
int payloadLength = -1;
|
||||
|
||||
// spectrum
|
||||
@@ -607,8 +607,8 @@ void updateCore() {
|
||||
}
|
||||
|
||||
if (inputCurrent.flags.needReinit) {
|
||||
static int sampleRateInpOld = ggWave->getSampleRateInp();
|
||||
static int sampleRateOutOld = ggWave->getSampleRateOut();
|
||||
static auto sampleRateInpOld = ggWave->getSampleRateInp();
|
||||
static auto sampleRateOutOld = ggWave->getSampleRateOut();
|
||||
GGWave::SampleFormat sampleFormatInpOld = ggWave->getSampleFormatInp();
|
||||
GGWave::SampleFormat sampleFormatOutOld = ggWave->getSampleFormatOut();
|
||||
auto rxProtocolsOld = ggWave->getRxProtocols();
|
||||
@@ -817,7 +817,7 @@ void renderMain() {
|
||||
struct Settings {
|
||||
int protocolId = GGWAVE_TX_PROTOCOL_AUDIBLE_FAST;
|
||||
bool isSampleRateOffset = false;
|
||||
int sampleRateOffset = -512;
|
||||
float sampleRateOffset = -512.0f;
|
||||
bool isFixedLength = false;
|
||||
int payloadLength = 8;
|
||||
float volume = 0.10f;
|
||||
@@ -1112,7 +1112,7 @@ void renderMain() {
|
||||
ImGui::SetCursorScreenPos({ posSave.x + kLabelWidth, posSave.y });
|
||||
}
|
||||
{
|
||||
const float df = float(statsCurrent.sampleRateBase)/statsCurrent.samplesPerFrame;
|
||||
const float df = statsCurrent.sampleRateBase/statsCurrent.samplesPerFrame;
|
||||
const auto & protocol = settings.txProtocols.at(GGWave::TxProtocolId(settings.protocolId));
|
||||
ImGui::Text("%6.2f Hz - %6.2f Hz", df*protocol.freqStart, df*(protocol.freqStart + 2*16*protocol.bytesPerTx));
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ void renderMain() {
|
||||
if (settings.isSampleRateOffset) {
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(0.5*ImGui::GetContentRegionAvailWidth());
|
||||
if (ImGui::SliderInt("Samples", &settings.sampleRateOffset, -1000, 1000)) {
|
||||
if (ImGui::SliderFloat("Samples", &settings.sampleRateOffset, -1000, 1000, "%.0f")) {
|
||||
g_buffer.inputUI.update = true;
|
||||
g_buffer.inputUI.flags.needReinit = true;
|
||||
g_buffer.inputUI.sampleRateOffset = settings.isSampleRateOffset ? settings.sampleRateOffset : 0;
|
||||
|
||||
Reference in New Issue
Block a user