mirror of
https://github.com/niellun/FastCarPlay.git
synced 2026-09-26 19:21:55 +02:00
Audio recording fixed
This commit is contained in:
@@ -24,9 +24,9 @@ void Logger::setLevel(int level)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level > static_cast<int>(Level::Verbose))
|
if (level > static_cast<int>(Level::Protocol))
|
||||||
{
|
{
|
||||||
_level = Level::Verbose;
|
_level = Level::Protocol;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+49
-16
@@ -3,6 +3,7 @@
|
|||||||
#include "protocol/protocol_const.h"
|
#include "protocol/protocol_const.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "common/logger.h"
|
#include "common/logger.h"
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
// Add sample size (buffer size in samples) to ChannelConfig
|
// Add sample size (buffer size in samples) to ChannelConfig
|
||||||
ChannelConfig PcmAudio::_configTable[] = {
|
ChannelConfig PcmAudio::_configTable[] = {
|
||||||
@@ -24,6 +25,7 @@ PcmAudio::PcmAudio(const char *name) : _name("default"),
|
|||||||
{
|
{
|
||||||
if (name && strlen(name) > 0)
|
if (name && strlen(name) > 0)
|
||||||
_name = name;
|
_name = name;
|
||||||
|
log_v("Created %s", _name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
PcmAudio::~PcmAudio()
|
PcmAudio::~PcmAudio()
|
||||||
@@ -31,12 +33,14 @@ PcmAudio::~PcmAudio()
|
|||||||
stop();
|
stop();
|
||||||
if (_thread.joinable())
|
if (_thread.joinable())
|
||||||
_thread.join();
|
_thread.join();
|
||||||
|
log_v("Destroyed %s", _name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmAudio::start(AtomicQueue<Message> *data, PcmAudio *fader)
|
void PcmAudio::start(AtomicQueue<Message> *data, PcmAudio *fader)
|
||||||
{
|
{
|
||||||
if (_active)
|
if (_active)
|
||||||
stop();
|
stop();
|
||||||
|
log_v("Starting %s", _name.c_str());
|
||||||
_fader = fader;
|
_fader = fader;
|
||||||
_data = data;
|
_data = data;
|
||||||
_active = true;
|
_active = true;
|
||||||
@@ -47,6 +51,7 @@ void PcmAudio::stop()
|
|||||||
{
|
{
|
||||||
if (!_active)
|
if (!_active)
|
||||||
return;
|
return;
|
||||||
|
log_v("Stopping %s", _name.c_str());
|
||||||
_active = false;
|
_active = false;
|
||||||
_data->notify();
|
_data->notify();
|
||||||
}
|
}
|
||||||
@@ -69,13 +74,11 @@ bool PcmAudio::isZero(const Message *msg)
|
|||||||
{
|
{
|
||||||
const uint64_t *p = (const uint64_t *)msg->data();
|
const uint64_t *p = (const uint64_t *)msg->data();
|
||||||
int n = msg->length() / 8;
|
int n = msg->length() / 8;
|
||||||
|
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
if (p[i] != 0)
|
if (p[i] != 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,9 +86,7 @@ void PcmAudio::fade(bool enable)
|
|||||||
{
|
{
|
||||||
_fade.store(enable);
|
_fade.store(enable);
|
||||||
if (!_playing)
|
if (!_playing)
|
||||||
{
|
|
||||||
_volume = enable ? Settings::audioFade : 1.0;
|
_volume = enable ? Settings::audioFade : 1.0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PcmAudio::fade(uint8_t *data, int32_t length)
|
void PcmAudio::fade(uint8_t *data, int32_t length)
|
||||||
@@ -95,7 +96,7 @@ void PcmAudio::fade(uint8_t *data, int32_t length)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int16_t *buf = reinterpret_cast<int16_t *>(data);
|
int16_t *buf = reinterpret_cast<int16_t *>(data);
|
||||||
for (size_t i = 0; i < length / 2; i++)
|
for (int i = 0; i < length / 2; i++)
|
||||||
{
|
{
|
||||||
if (fade)
|
if (fade)
|
||||||
{
|
{
|
||||||
@@ -116,15 +117,29 @@ void PcmAudio::play(SDL_AudioDeviceID device, ChannelConfig config, int32_t segm
|
|||||||
{
|
{
|
||||||
uint8_t zeroSegments = 0;
|
uint8_t zeroSegments = 0;
|
||||||
bool nonZero = false;
|
bool nonZero = false;
|
||||||
|
|
||||||
int prefill = config.channels == 1 ? Settings::audioDelayCall : Settings::audioDelay;
|
int prefill = config.channels == 1 ? Settings::audioDelayCall : Settings::audioDelay;
|
||||||
int segmentTimeMs = 1000.0 * segmentSize / (config.rate * config.channels * 2.0);
|
int segmentTimeMs = 1000.0 * segmentSize / (config.rate * config.channels * 2.0);
|
||||||
|
int waitTimeMs = (prefill + 1) * segmentTimeMs;
|
||||||
|
log_i("Prepare to play %s %dkHz %s chunk %d ~%dms prefill %d ~%dms", _name.c_str(),
|
||||||
|
config.rate,
|
||||||
|
(config.channels == 2 ? "stereo" : "mono"),
|
||||||
|
segmentSize,
|
||||||
|
segmentTimeMs,
|
||||||
|
prefill,
|
||||||
|
waitTimeMs);
|
||||||
|
|
||||||
log_i("Prepare to play %s %dkHz %s prefill %d ~%dms chunk %d", _name.c_str(), config.rate, (config.channels == 2 ? "stereo" : "mono"), prefill, segmentTimeMs, segmentSize);
|
if (!_data->waitFor(_active, AUDIO_RESET_SECONDS * 1000, prefill))
|
||||||
|
|
||||||
if (!_data->waitFor(_active, segmentTimeMs * (prefill + 1) * 3, prefill))
|
|
||||||
{
|
{
|
||||||
_data->clear();
|
_data->clear();
|
||||||
log_w("Not enough data to play %s %dkHz %s prefill %d ~%dms chunk %d", _name.c_str(), config.rate, (config.channels == 2 ? "stereo" : "mono"), prefill, segmentTimeMs, segmentSize);
|
log_w("Not enough data to play %s %dkHz %s chunk %d ~%dms prefill %d ~%dms",
|
||||||
|
_name.c_str(),
|
||||||
|
config.rate,
|
||||||
|
(config.channels == 2 ? "stereo" : "mono"),
|
||||||
|
segmentSize,
|
||||||
|
segmentTimeMs,
|
||||||
|
prefill,
|
||||||
|
waitTimeMs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,11 +157,15 @@ void PcmAudio::play(SDL_AudioDeviceID device, ChannelConfig config, int32_t segm
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fade(segment->data(), segment->length());
|
fade(segment->data(), segment->length());
|
||||||
|
|
||||||
SDL_QueueAudio(device, segment->data(), segment->length());
|
SDL_QueueAudio(device, segment->data(), segment->length());
|
||||||
|
|
||||||
if (!_playing)
|
if (!_playing && prefill-- <= 0)
|
||||||
{
|
{
|
||||||
log_d("Start playing %s %dkHz %s", _name.c_str(), config.rate, (config.channels == 2 ? "stereo" : "mono"));
|
log_d("Start playing %s %dkHz %s",
|
||||||
|
_name.c_str(),
|
||||||
|
config.rate,
|
||||||
|
(config.channels == 2 ? "stereo" : "mono"));
|
||||||
SDL_PauseAudioDevice(device, 0);
|
SDL_PauseAudioDevice(device, 0);
|
||||||
_playing = true;
|
_playing = true;
|
||||||
}
|
}
|
||||||
@@ -169,7 +188,7 @@ void PcmAudio::play(SDL_AudioDeviceID device, ChannelConfig config, int32_t segm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_data->waitFor(_active, segmentTimeMs * 3))
|
if (!_data->waitFor(_active, waitTimeMs))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,11 +198,12 @@ void PcmAudio::loop()
|
|||||||
std::string threadName = "audio-" + _name;
|
std::string threadName = "audio-" + _name;
|
||||||
setThreadName(threadName.c_str());
|
setThreadName(threadName.c_str());
|
||||||
|
|
||||||
log_d("Audio %s thread started", _name.c_str());
|
log_d("Started thread %s", _name.c_str());
|
||||||
|
|
||||||
SDL_AudioDeviceID device = 0;
|
SDL_AudioDeviceID device = 0;
|
||||||
SDL_AudioSpec spec;
|
SDL_AudioSpec spec;
|
||||||
|
|
||||||
|
time_t playEnd = time(NULL);
|
||||||
while (_data->wait(_active))
|
while (_data->wait(_active))
|
||||||
{
|
{
|
||||||
const Message *segment = _data->peek();
|
const Message *segment = _data->peek();
|
||||||
@@ -213,13 +233,20 @@ void PcmAudio::loop()
|
|||||||
device = SDL_OpenAudioDevice(nullptr, 0, &spec, nullptr, 0);
|
device = SDL_OpenAudioDevice(nullptr, 0, &spec, nullptr, 0);
|
||||||
if (device == 0)
|
if (device == 0)
|
||||||
{
|
{
|
||||||
log_w("Failed to open audio %s > %s", _name.c_str(), SDL_GetError());
|
log_w("Failed to open audio %s %dkHz %s samples %d > %s",
|
||||||
|
_name.c_str(),
|
||||||
|
config.rate,
|
||||||
|
(config.channels == 2 ? "stereo" : "mono"),
|
||||||
|
Settings::audioBuffer * config.scale, SDL_GetError());
|
||||||
SDL_Delay(100);
|
SDL_Delay(100);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (difftime(time(NULL), playEnd) > AUDIO_RESET_SECONDS)
|
||||||
|
SDL_ClearQueuedAudio(device);
|
||||||
|
|
||||||
if (_fader)
|
if (_fader)
|
||||||
_fader->fade(true);
|
_fader->fade(true);
|
||||||
play(device, config, segment->length());
|
play(device, config, segment->length());
|
||||||
@@ -227,13 +254,19 @@ void PcmAudio::loop()
|
|||||||
if (_fader)
|
if (_fader)
|
||||||
_fader->fade(false);
|
_fader->fade(false);
|
||||||
SDL_PauseAudioDevice(device, 1);
|
SDL_PauseAudioDevice(device, 1);
|
||||||
log_i("Stop playing %s", _name.c_str());
|
playEnd = time(NULL);
|
||||||
|
log_d("Stop playing %s %dkHz %s",
|
||||||
|
_name.c_str(),
|
||||||
|
config.rate,
|
||||||
|
(config.channels == 2 ? "stereo" : "mono"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device)
|
if (device != 0)
|
||||||
{
|
{
|
||||||
SDL_PauseAudioDevice(device, 1);
|
SDL_PauseAudioDevice(device, 1);
|
||||||
SDL_ClearQueuedAudio(device);
|
SDL_ClearQueuedAudio(device);
|
||||||
SDL_CloseAudioDevice(device);
|
SDL_CloseAudioDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_v("Stopped thread %s", _name.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#define FADE_IN_SPEED 0.00001
|
#define FADE_IN_SPEED 0.00001
|
||||||
#define FADE_OUT_SPEED 0.0001
|
#define FADE_OUT_SPEED 0.0001
|
||||||
#define FADE_ZERO_SEGMENTS 10
|
#define FADE_ZERO_SEGMENTS 10
|
||||||
|
#define AUDIO_RESET_SECONDS 5
|
||||||
|
|
||||||
struct ChannelConfig
|
struct ChannelConfig
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ void Connection::writeLoop(libusb_device_handle *handler, uint8_t ep)
|
|||||||
|
|
||||||
int transferred;
|
int transferred;
|
||||||
libusb_bulk_transfer(handler, ep, message->header(), message->headerSize(), &transferred, 0);
|
libusb_bulk_transfer(handler, ep, message->header(), message->headerSize(), &transferred, 0);
|
||||||
|
message->setOffset(0);
|
||||||
if (message->length() > 0)
|
if (message->length() > 0)
|
||||||
libusb_bulk_transfer(handler, ep, message->data(), message->length(), &transferred, 0);
|
libusb_bulk_transfer(handler, ep, message->data(), message->length(), &transferred, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ ConnectionReader::ConnectionReader()
|
|||||||
|
|
||||||
ConnectionReader::~ConnectionReader()
|
ConnectionReader::~ConnectionReader()
|
||||||
{
|
{
|
||||||
log_v("Destroying");
|
|
||||||
|
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
for (Context &context : _transfers)
|
for (Context &context : _transfers)
|
||||||
|
|||||||
Reference in New Issue
Block a user