mumble-voip_mumble/src/mumble/JackAudio.h

182 lines
6.0 KiB
C++

// Copyright 2018-2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#ifndef MUMBLE_MUMBLE_JACKAUDIO_H_
#define MUMBLE_MUMBLE_JACKAUDIO_H_
#include "AudioInput.h"
#include "AudioOutput.h"
#include <QtCore/QLibrary>
#include <QtCore/QSemaphore>
#include <QtCore/QVector>
#include <QtCore/QWaitCondition>
#include <jack/types.h>
#define JACK_MAX_OUTPUT_PORTS 2
#define JACK_BUFFER_PERIODS 3
// Definitions from <jack/ringbuffer.h>
typedef void *jack_ringbuffer_t;
struct jack_ringbuffer_data_t {
char *buf;
size_t len;
};
typedef QVector< jack_port_t * > JackPorts;
typedef QVector< jack_default_audio_sample_t * > JackBuffers;
class JackAudioInit;
class JackAudioSystem : public QObject {
friend JackAudioInit;
private:
Q_OBJECT
Q_DISABLE_COPY(JackAudioSystem)
protected:
bool bAvailable;
uint8_t users;
QMutex qmWait;
QLibrary qlJack;
jack_client_t *client;
static int processCallback(jack_nframes_t frames, void *);
static int sampleRateCallback(jack_nframes_t, void *);
static int bufferSizeCallback(jack_nframes_t frames, void *);
static void shutdownCallback(void *);
const char *(*jack_get_version_string)();
const char **(*jack_get_ports)(jack_client_t *client, const char *port_name_pattern, const char *type_name_pattern,
unsigned long flags);
char *(*jack_get_client_name)(jack_client_t *client);
char *(*jack_port_name)(jack_port_t *port);
int (*jack_client_close)(jack_client_t *client);
int (*jack_activate)(jack_client_t *client);
int (*jack_deactivate)(jack_client_t *client);
int (*jack_set_process_callback)(jack_client_t *client, JackProcessCallback process_callback, void *arg);
int (*jack_set_sample_rate_callback)(jack_client_t *client, JackSampleRateCallback process_callback, void *arg);
int (*jack_set_buffer_size_callback)(jack_client_t *client, JackBufferSizeCallback process_callback, void *arg);
int (*jack_on_shutdown)(jack_client_t *client, JackShutdownCallback process_callback, void *arg);
int (*jack_connect)(jack_client_t *client, const char *source_port, const char *destination_port);
int (*jack_port_disconnect)(jack_client_t *client, jack_port_t *port);
int (*jack_port_unregister)(jack_client_t *client, jack_port_t *port);
int (*jack_port_flags)(const jack_port_t *port);
void *(*jack_port_get_buffer)(jack_port_t *port, jack_nframes_t frames);
void (*jack_free)(void *ptr);
jack_client_t *(*jack_client_open)(const char *client_name, jack_options_t options, jack_status_t *status, ...);
jack_nframes_t (*jack_get_sample_rate)(jack_client_t *client);
jack_nframes_t (*jack_get_buffer_size)(jack_client_t *client);
jack_port_t *(*jack_port_by_name)(jack_client_t *client, const char *port_name);
jack_port_t *(*jack_port_register)(jack_client_t *client, const char *port_name, const char *port_type,
unsigned long flags, unsigned long buffer_size);
jack_ringbuffer_t *(*jack_ringbuffer_create)(size_t sz);
void (*jack_ringbuffer_free)(jack_ringbuffer_t *rb);
int (*jack_ringbuffer_mlock)(jack_ringbuffer_t *rb);
size_t (*jack_ringbuffer_read)(jack_ringbuffer_t *rb, char *dest, size_t cnt);
size_t (*jack_ringbuffer_read_space)(const jack_ringbuffer_t *rb);
size_t (*jack_ringbuffer_write)(jack_ringbuffer_t *rb, const char *src, size_t cnt);
void (*jack_ringbuffer_get_write_vector)(const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec);
size_t (*jack_ringbuffer_write_space)(const jack_ringbuffer_t *rb);
void (*jack_ringbuffer_write_advance)(jack_ringbuffer_t *rb, size_t cnt);
public:
QHash< QString, QString > qhInput;
QHash< QString, QString > qhOutput;
bool isOk();
uint8_t outPorts();
jack_nframes_t sampleRate();
jack_nframes_t bufferSize();
JackPorts getPhysicalPorts(const uint8_t flags);
void *getPortBuffer(jack_port_t *port, const jack_nframes_t frames);
jack_port_t *registerPort(const char *name, const uint8_t flags);
bool unregisterPort(jack_port_t *port);
bool connectPort(jack_port_t *sourcePort, jack_port_t *destinationPort);
bool disconnectPort(jack_port_t *port);
jack_ringbuffer_t *ringbufferCreate(const size_t size);
void ringbufferFree(jack_ringbuffer_t *buffer);
int ringbufferMlock(jack_ringbuffer_t *buffer);
size_t ringbufferRead(jack_ringbuffer_t *buffer, const size_t size, void *destination);
size_t ringbufferReadSpace(const jack_ringbuffer_t *buffer);
size_t ringbufferWrite(jack_ringbuffer_t *buffer, const size_t size, const void *source);
void ringbufferGetWriteVector(const jack_ringbuffer_t *buffer, jack_ringbuffer_data_t *vector);
size_t ringbufferWriteSpace(const jack_ringbuffer_t *buffer);
void ringbufferWriteAdvance(jack_ringbuffer_t *buffer, const size_t size);
bool initialize();
void deinitialize();
bool activate();
void deactivate();
JackAudioSystem();
~JackAudioSystem();
};
class JackAudioInput : public AudioInput {
private:
Q_OBJECT
Q_DISABLE_COPY(JackAudioInput)
protected:
volatile bool bReady;
QMutex qmWait;
QSemaphore qsSleep;
jack_port_t *port;
jack_ringbuffer_t *buffer;
size_t bufferSize;
public:
bool isReady();
bool process(const jack_nframes_t frames);
bool allocBuffer(const jack_nframes_t frames);
bool activate();
void deactivate();
bool registerPorts();
bool unregisterPorts();
void connectPorts();
bool disconnectPorts();
void run() Q_DECL_OVERRIDE;
JackAudioInput();
~JackAudioInput() Q_DECL_OVERRIDE;
};
class JackAudioOutput : public AudioOutput {
private:
Q_OBJECT
Q_DISABLE_COPY(JackAudioOutput)
protected:
volatile bool bReady;
QMutex qmWait;
QSemaphore qsSleep;
JackPorts ports;
JackBuffers outputBuffers;
jack_ringbuffer_t *buffer;
public:
bool isReady();
bool process(const jack_nframes_t frames);
bool allocBuffer(const jack_nframes_t frames);
bool activate();
void deactivate();
bool registerPorts();
bool unregisterPorts();
void connectPorts();
bool disconnectPorts();
void run() Q_DECL_OVERRIDE;
JackAudioOutput();
~JackAudioOutput() Q_DECL_OVERRIDE;
};
#endif