Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ALSA backend: Multi ALSA device support #608

Open
wants to merge 42 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
bb0fcf0
posix: fifo: use right prototype
May 7, 2019
c811168
posix: socket: Add missing time header include
May 7, 2019
e064932
Add QNX platform specific implementations
May 7, 2019
d86d2be
AudioAdapter: Use empty Adapter also for QNX
May 7, 2019
8521b98
qnx: sigaction: do not set SA_RESTART flag
May 7, 2019
5dfc216
qnx: shm: Include right header
May 7, 2019
012fe02
shm: Add semget() and semop() replacement for QNX
May 22, 2019
7bed71c
alsa: Extract snd_pcm_start/poll_descriptors/avail_update
Sep 6, 2019
71ecea6
alsa backend for qnx
Feb 4, 2020
8e8ae8e
alsa: Simplify get state on linux
Oct 15, 2019
fc1d6a5
Support QNX build with WAF
May 7, 2019
831f4e6
Workaround: JackClient: Fix printf NULL issue
DeviLaxmii Jan 20, 2020
92911ea
alsa: Add multi dev support
Sep 23, 2019
eb0739d
jack: alsa_driver: add check alsa_driver_poll_descriptor
kapildevpatel Feb 7, 2020
1ef6fb9
JackRequest: Add missing comma
Sep 27, 2019
4ed6112
jack common: add api jack_client_reload_master
Sep 27, 2019
521874d
jack alsa: introduce alsa_driver_info_t [2/2]
Oct 2, 2019
78e97af
jack alsa: implement restart request [1/3]
Oct 1, 2019
b88a85a
jack alsa: implement restart request [2/3]
Oct 1, 2019
418f4ed
jack alsa: implement restart request [3/3]
Oct 1, 2019
f45f3cc
jack alsa: move linking functionality to separate function
Oct 16, 2019
316aee4
jack alsa: do not return early
Oct 17, 2019
3de4858
jack alsa: add array_string_t flags
Sep 30, 2019
9a25d22
jack alsa: reoganize code for readability
Sep 30, 2019
99bb68b
jack alsa: implement ALSA_DRIVER_FEAT_START_CLOSED
Oct 2, 2019
9a3bdd6
jack alsa: reintroduce special hardware handling
Oct 2, 2019
27a676c
jack alsa: reformat to allow easier managing of priorities
Oct 16, 2019
e994144
jack alsa: add DriverMode as enum
Oct 17, 2019
eb17137
jack alsa: add shutdown mode of operation
Oct 16, 2019
950497d
jack alsa: optimize operation of reload request
Oct 16, 2019
4d60f5b
jack alsa: rework 'x' and 'c' options
Jan 2, 2020
cdddc81
alsa_driver: remove additional delete to avoid double free
Jan 14, 2020
104ca04
QTISA-195 alsa: qnx call plugin flush for every device separately
Feb 20, 2020
894ca0c
alsa: rework error reporting from alsa_driver_wait
Feb 7, 2020
0187cf6
QTISA-183 alsa: add more logs improve debugging
Feb 20, 2020
3fb9fec
QTISA-183 alsa: make alsa_driver_xrun_recovery global
Feb 21, 2020
604c485
QTISA-183 alsa: remove recovery from alsa_driver_wait
Feb 21, 2020
ee274e7
QTISA-183 audio: implement retry for failed read write
Feb 25, 2020
b5ede1c
QTISA-183 alsa: allow recovery for read and write
Feb 25, 2020
eaca20d
QTISA-188 alsa: fix implementation for shorts_first
Feb 26, 2020
0e95738
QTISA-188 alsa: modify sample rate only when device was opened
Feb 26, 2020
a154717
example: Add client for reloading the master
Mar 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.PHONY: all
all:
CC=${QNX_HOST}/usr/bin/aarch64-unknown-nto-qnx7.0.0-gcc CXX=${QNX_HOST}/usr/bin/aarch64-unknown-nto-qnx7.0.0-g++ AR=${QNX_HOST}/usr/bin/aarch64-unknown-nto-qnx7.0.0-ar LDFLAGS="-L${INSTALL_ROOT_nto}/aarch64le/lib -L${INSTALL_ROOT_nto}/aarch64le/usr/lib -L${QNX_TARGET}/aarch64le/lib -L${QNX_TARGET}/aarch64le/usr/lib" PKG_CONFIG_LIBDIR=${INSTALL_ROOT_nto}/aarch64le/usr/lib/pkgconfig ./waf configure --platform=qnx --prefix=/usr --libdir=/usr/lib64
./waf build
./waf install --destdir=${INSTALL_ROOT_nto}/aarch64le

.PHONY: install
install: all

.PHONY:clean
clean:
# ignore error codes otherwise it would for example fail if clean is called before configure
-./waf clean

16 changes: 16 additions & 0 deletions common/JackAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ extern "C"
LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]);
LIB_EXPORT int jack_uuid_empty(jack_uuid_t);

LIB_EXPORT int jack_client_reload_master(jack_client_t* ext_client);

#ifdef __cplusplus
}
#endif
Expand Down Expand Up @@ -2140,3 +2142,17 @@ LIB_EXPORT int jack_uuid_empty(jack_uuid_t u)
{
return u == JACK_UUID_EMPTY_INITIALIZER;
}

LIB_EXPORT int jack_client_reload_master(jack_client_t* ext_client)
{
JackGlobals::CheckContext("jack_client_reload_master");

JackClient* client = (JackClient*)ext_client;
if (client == NULL) {
jack_error("jack_client_reload_master called with a NULL client");
return -1;
} else {
WaitGraphChange();
return client->ClientReloadMaster();
}
}
4 changes: 2 additions & 2 deletions common/JackAudioAdapterInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endif

#include "JackAudioAdapter.h"
#ifndef MY_TARGET_OS_IPHONE
#if !defined(MY_TARGET_OS_IPHONE) && !defined(__QNXNTO__)
#include "JackLibSampleRateResampler.h"
#endif
#include "JackTime.h"
Expand Down Expand Up @@ -185,7 +185,7 @@ namespace Jack
fRunning = false;
}

#ifdef MY_TARGET_OS_IPHONE
#if defined(MY_TARGET_OS_IPHONE) || defined(__QNXNTO__)
void JackAudioAdapterInterface::Create()
{}
#else
Expand Down
22 changes: 17 additions & 5 deletions common/JackAudioDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,19 @@ int JackAudioDriver::Write()

int JackAudioDriver::Process()
{
return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
int err = 0;
int retries = -1;

while (retries++ < fMaxRetryCount) {
err = (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
if (err == 0) {
break;
}

jack_error("JackAudioDriver::Process failed, retry %d", retries);
}

return err;
}

/*
Expand All @@ -211,13 +223,13 @@ int JackAudioDriver::ProcessAsync()
{
// Read input buffers for the current cycle
if (Read() < 0) {
jack_error("JackAudioDriver::ProcessAsync: read error, stopping...");
jack_error("JackAudioDriver::ProcessAsync: read error");
return -1;
}

// Write output buffers from the previous cycle
if (Write() < 0) {
jack_error("JackAudioDriver::ProcessAsync: write error, stopping...");
jack_error("JackAudioDriver::ProcessAsync: write error");
return -1;
}

Expand Down Expand Up @@ -285,7 +297,7 @@ int JackAudioDriver::ProcessSync()
{
// Read input buffers for the current cycle
if (Read() < 0) {
jack_error("JackAudioDriver::ProcessSync: read error, stopping...");
jack_error("JackAudioDriver::ProcessSync: read error");
return -1;
}

Expand All @@ -294,7 +306,7 @@ int JackAudioDriver::ProcessSync()

// Write output buffers from the current cycle
if (Write() < 0) {
jack_error("JackAudioDriver::ProcessSync: write error, stopping...");
jack_error("JackAudioDriver::ProcessSync: write error");
return -1;
}

Expand Down
2 changes: 2 additions & 0 deletions common/JackAudioDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver
void ProcessGraphSyncMaster();
void ProcessGraphSyncSlave();

static const int fMaxRetryCount = 5;

public:

JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
Expand Down
3 changes: 3 additions & 0 deletions common/JackChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ class JackClientChannelInterface
virtual void ClientDeactivate(int refnum, int* result)
{}

virtual void ClientReloadMaster(int* result)
{}

virtual void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
{}
virtual void PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
Expand Down
16 changes: 16 additions & 0 deletions common/JackClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

using namespace std;

#ifdef __QNXNTO__
void __attribute__((constructor)) init_output_for_percent_s_NULL_for_clients();
void init_output_for_percent_s_NULL_for_clients()
{
extern const char *output_for_percent_s_NULL;
output_for_percent_s_NULL = "(null)";
}
#endif

namespace Jack
{

Expand Down Expand Up @@ -493,6 +502,13 @@ int JackClient::Deactivate()
if (IsRealTime()) {
fThread.Kill();
}
return result;
}

int JackClient::ClientReloadMaster()
{
int result = -1;
fChannel->ClientReloadMaster(&result);
return result;
}

Expand Down
2 changes: 2 additions & 0 deletions common/JackClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class SERVER_EXPORT JackClient : public JackClientInterface, public JackRunnable
virtual int Activate();
virtual int Deactivate();

virtual int ClientReloadMaster();

// Context
virtual int SetBufferSize(jack_nframes_t buffer_size);
virtual int SetFreeWheel(int onoff);
Expand Down
5 changes: 4 additions & 1 deletion common/JackControlAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,10 @@ jackctl_setup_signals(
sigfillset(&allsignals);
action.sa_handler = signal_handler;
action.sa_mask = allsignals;
action.sa_flags = SA_RESTART|SA_RESETHAND;
action.sa_flags = SA_RESETHAND;
#ifndef __QNXNTO__
action.sa_flags |= SA_RESTART;
#endif

for (i = 1; i < NSIG; i++)
{
Expand Down
9 changes: 9 additions & 0 deletions common/JackDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ int JackDriver::Open(jack_nframes_t buffer_size,
fClientControl.fRefNum = refnum;
fClientControl.fActive = true;
fEngineControl->fDriverNum++;
if (buffer_size > BUFFER_SIZE_MAX) {
jack_error("Buffer size %ld exceeds BUFFER_SIZE_MAX %d", buffer_size, BUFFER_SIZE_MAX);
return -1;
}
if (buffer_size > 0) {
fEngineControl->fBufferSize = buffer_size;
}
Expand Down Expand Up @@ -351,6 +355,11 @@ int JackDriver::Stop()
return StopSlaves();
}

int JackDriver::Reload()
{
return 0;
}

int JackDriver::StartSlaves()
{
int res = 0;
Expand Down
2 changes: 2 additions & 0 deletions common/JackDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class SERVER_EXPORT JackDriverInterface

virtual int Start() = 0;
virtual int Stop() = 0;
virtual int Reload() = 0;

virtual bool IsFixedBufferSize() = 0;
virtual int SetBufferSize(jack_nframes_t buffer_size) = 0;
Expand Down Expand Up @@ -227,6 +228,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface

virtual int Start();
virtual int Stop();
virtual int Reload();

// For "master" driver
int ProcessReadSlaves();
Expand Down
7 changes: 7 additions & 0 deletions common/JackGenericClientChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ void JackGenericClientChannel::ClientDeactivate(int refnum, int* result)
ServerSyncCall(&req, &res, result);
}

void JackGenericClientChannel::ClientReloadMaster(int *result)
{
JackClientReloadMasterRequest req;
JackResult res;
ServerSyncCall(&req, &res, result);
}

void JackGenericClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
{
JackPortRegisterRequest req(refnum, name, type, flags, buffer_size);
Expand Down
2 changes: 2 additions & 0 deletions common/JackGenericClientChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class JackGenericClientChannel : public detail::JackClientChannelInterface
void ClientActivate(int refnum, int is_real_time, int* result);
void ClientDeactivate(int refnum, int* result);

void ClientReloadMaster(int* result);

void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result);
void PortUnRegister(int refnum, jack_port_id_t port_index, int* result);

Expand Down
28 changes: 27 additions & 1 deletion common/JackRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ struct JackRequest
kGetUUIDByClient = 37,
kClientHasSessionCallback = 38,
kComputeTotalLatencies = 39,
kPropertyChangeNotify = 40
kPropertyChangeNotify = 40,
kClientReloadMaster = 41,
};

RequestType fType;
Expand Down Expand Up @@ -1736,6 +1737,31 @@ struct JackClientNotification

};

/*!
\brief Restart Master Backend Request.
*/

struct JackClientReloadMasterRequest : public JackRequest
{
JackClientReloadMasterRequest(): JackRequest(JackRequest::kClientReloadMaster)
{
}

int Read(detail::JackChannelTransactionInterface* trans)
{
CheckSize();
return 0;
}

int Write(detail::JackChannelTransactionInterface* trans)
{
CheckRes(JackRequest::Write(trans, Size()));
return 0;
}

int Size() { return 0; }
};

} // end of namespace

#endif
10 changes: 10 additions & 0 deletions common/JackRequestDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s
break;
}

case JackRequest::kClientReloadMaster: {
jack_log("JackRequest::ClientReloadMaster");
JackClientReloadMasterRequest req;
JackResult res;
CheckRead(req, socket);
res.fResult = fServer->ReloadMaster();
CheckWrite("JackRequest::ClientReloadMaster", socket);
break;
}

default:
jack_error("Unknown request %ld", type);
return -1;
Expand Down
5 changes: 5 additions & 0 deletions common/JackServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par
return -1;
}

int JackServer::ReloadMaster()
{
return fAudioDriver->Reload();
}

//----------------------
// Transport management
//----------------------
Expand Down
1 change: 1 addition & 0 deletions common/JackServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class SERVER_EXPORT JackServer
JackDriverInfo* AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params);
void RemoveSlave(JackDriverInfo* info);
int SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params);
int ReloadMaster();

// Object access
JackLockedEngine* GetEngine();
Expand Down
22 changes: 22 additions & 0 deletions common/JackThreadedDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,28 @@ int JackThreadedDriver::Stop()
return 0;
}

int JackThreadedDriver::Reload()
{
if (Stop() < 0) {
jack_error("JackThreadedDriver::Reload stop failed");
return -1;
}

// not able to use Close() and Open() since we dont have original Open() parameters, these
// are internal to fDriver, reload should reopen with same parameters
if (fDriver->Reload() < 0) {
jack_error("JackThreadedDriver::Reload reload failed");
return -1;
}

if (Start() < 0) {
jack_error("JackThreadedDriver::Reload start failed");
return -1;
}

return 0;
}

bool JackThreadedDriver::Execute()
{
return (Process() == 0);
Expand Down
1 change: 1 addition & 0 deletions common/JackThreadedDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi

virtual int Start();
virtual int Stop();
virtual int Reload();

virtual bool IsFixedBufferSize();
virtual int SetBufferSize(jack_nframes_t buffer_size);
Expand Down
16 changes: 16 additions & 0 deletions common/jack/jack.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,22 @@ int jack_client_close (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT;
*/
int jack_client_name_size (void) JACK_OPTIONAL_WEAK_EXPORT;

/**
* Reloads audio backend.
*
* This is useful when client wants audio backend to reload its state.
* Currently used only for alsa audio backend.
*
* Alsa backend will close or open audio devices on reload depending on
* the state of the ports asociated with audio device. If all ports
* are disconnected audio device is closed, opened otherwise. This
* behaviour is modifiable by alsa backend options provided to jackd
* on startup.
*
* @return 0 if successful.
*/
int jack_client_reload_master(jack_client_t* ext_client) JACK_OPTIONAL_WEAK_EXPORT;

/**
* @return pointer to actual client name. This is useful when @ref
* JackUseExactName is not specified on open and @ref
Expand Down
2 changes: 1 addition & 1 deletion common/jack/systemdeps.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#endif /* _WIN32 && !__CYGWIN__ && !GNU_WIN32 */

#if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) || defined(__unix__) || defined(__CYGWIN__) || defined(GNU_WIN32)
#if defined(__APPLE__) || defined(__linux__) || defined(__sun__) || defined(sun) || defined(__unix__) || defined(__CYGWIN__) || defined(GNU_WIN32) || defined(__QNXNTO__)

#if defined(__CYGWIN__) || defined(GNU_WIN32)
#include <stdint.h>
Expand Down