Add native io-audio backend for jackdpull/244/head
| @@ -48,7 +48,7 @@ int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) | |||
| fGraphManager->SetBufferSize(buffer_size); | |||
| fEngineControl->UpdateTimeOut(); | |||
| UpdateLatencies(); | |||
| update_latencies(); | |||
| // Redirected on slaves drivers... | |||
| return JackDriver::SetBufferSize(buffer_size); | |||
| @@ -85,7 +85,7 @@ int JackAudioDriver::Open(jack_nframes_t buffer_size, | |||
| monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); | |||
| } | |||
| void JackAudioDriver::UpdateLatencies() | |||
| void JackAudioDriver::update_latencies() | |||
| { | |||
| jack_latency_range_t input_range; | |||
| jack_latency_range_t output_range; | |||
| @@ -159,7 +159,7 @@ int JackAudioDriver::Attach() | |||
| } | |||
| } | |||
| UpdateLatencies(); | |||
| update_latencies(); | |||
| return 0; | |||
| } | |||
| @@ -49,7 +49,7 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver | |||
| jack_default_audio_sample_t* GetMonitorBuffer(int port_index); | |||
| void HandleLatencyCallback(int status); | |||
| virtual void UpdateLatencies(); | |||
| virtual void update_latencies(); | |||
| int ProcessAsync(); | |||
| void ProcessGraphAsync(); | |||
| @@ -208,9 +208,3 @@ SERVER_EXPORT jack_time_t GetMicroSeconds() | |||
| { | |||
| return _jack_get_microseconds(); | |||
| } | |||
| SERVER_EXPORT jack_time_t jack_get_microseconds() | |||
| { | |||
| return _jack_get_microseconds(); | |||
| } | |||
| @@ -0,0 +1,309 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| $Id: driver.h,v 1.2 2005/11/23 11:24:29 letz Exp $ | |||
| */ | |||
| #ifndef __jack_driver_h__ | |||
| #define __jack_driver_h__ | |||
| #include <pthread.h> | |||
| #include "types.h" | |||
| #include "jslist.h" | |||
| #include "driver_interface.h" | |||
| #ifdef __cplusplus | |||
| extern "C" | |||
| { | |||
| #endif | |||
| typedef float gain_t; | |||
| typedef long channel_t; | |||
| typedef enum { | |||
| Lock = 0x1, | |||
| NoLock = 0x2, | |||
| Sync = 0x4, | |||
| NoSync = 0x8 | |||
| } ClockSyncStatus; | |||
| typedef void (*ClockSyncListenerFunction)(channel_t, ClockSyncStatus, void*); | |||
| typedef struct | |||
| { | |||
| unsigned long id; | |||
| ClockSyncListenerFunction function; | |||
| void *arg; | |||
| } | |||
| ClockSyncListener; | |||
| struct _jack_engine; | |||
| struct _jack_driver; | |||
| typedef int (*JackDriverAttachFunction)(struct _jack_driver *, | |||
| struct _jack_engine *); | |||
| typedef int (*JackDriverDetachFunction)(struct _jack_driver *, | |||
| struct _jack_engine *); | |||
| typedef int (*JackDriverReadFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverWriteFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverNullCycleFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverStopFunction)(struct _jack_driver *); | |||
| typedef int (*JackDriverStartFunction)(struct _jack_driver *); | |||
| typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| /* | |||
| Call sequence summary: | |||
| 1) engine loads driver via runtime dynamic linking | |||
| - calls jack_driver_load | |||
| - we call dlsym for "driver_initialize" and execute it | |||
| 2) engine attaches to driver | |||
| 3) engine starts driver | |||
| 4) driver runs its own thread, calling | |||
| while () { | |||
| driver->wait (); | |||
| driver->engine->run_cycle () | |||
| } | |||
| 5) engine stops driver | |||
| 6) engine detaches from driver | |||
| 7) engine calls driver `finish' routine | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| typedef struct _jack_driver | |||
| { | |||
| /* The _jack_driver structure fields are included at the beginning of | |||
| each driver-specific structure using the JACK_DRIVER_DECL macro, | |||
| which is defined below. The comments that follow describe each | |||
| common field. | |||
| The driver should set this to be the interval it expects to elapse | |||
| between returning from the `wait' function. if set to zero, it | |||
| implies that the driver does not expect regular periodic wakeups. | |||
| jack_time_t period_usecs; | |||
| The driver should set this within its "wait" function to indicate | |||
| the UST of the most recent determination that the engine cycle | |||
| should run. it should not be set if the "extra_fd" argument of | |||
| the wait function is set to a non-zero value. | |||
| jack_time_t last_wait_ust; | |||
| These are not used by the driver. They should not be written to or | |||
| modified in any way | |||
| void *handle; | |||
| struct _jack_internal_client *internal_client; | |||
| This should perform any cleanup associated with the driver. it will | |||
| be called when jack server process decides to get rid of the | |||
| driver. in some systems, it may not be called at all, so the driver | |||
| should never rely on a call to this. it can set it to NULL if | |||
| it has nothing do do. | |||
| void (*finish)(struct _jack_driver *); | |||
| The JACK engine will call this when it wishes to attach itself to | |||
| the driver. the engine will pass a pointer to itself, which the driver | |||
| may use in anyway it wishes to. the driver may assume that this | |||
| is the same engine object that will make `wait' calls until a | |||
| `detach' call is made. | |||
| JackDriverAttachFunction attach; | |||
| The JACK engine will call this when it is finished using a driver. | |||
| JackDriverDetachFunction detach; | |||
| The JACK engine will call this when it wants to wait until the | |||
| driver decides that its time to process some data. the driver returns | |||
| a count of the number of audioframes that can be processed. | |||
| it should set the variable pointed to by `status' as follows: | |||
| zero: the wait completed normally, processing may begin | |||
| negative: the wait failed, and recovery is not possible | |||
| positive: the wait failed, and the driver stopped itself. | |||
| a call to `start' will return the driver to | |||
| a correct and known state. | |||
| the driver should also fill out the `delayed_usecs' variable to | |||
| indicate any delay in its expected periodic execution. for example, | |||
| if it discovers that its return from poll(2) is later than it | |||
| expects it to be, it would place an estimate of the delay | |||
| in this variable. the engine will use this to decide if it | |||
| plans to continue execution. | |||
| JackDriverWaitFunction wait; | |||
| The JACK engine will call this to ask the driver to move | |||
| data from its inputs to its output port buffers. it should | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| This function will always be called after the wait function (above). | |||
| JackDriverReadFunction read; | |||
| The JACK engine will call this to ask the driver to move | |||
| data from its input port buffers to its outputs. it should | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| this function will always be called after the read function (above). | |||
| JackDriverWriteFunction write; | |||
| The JACK engine will call this after the wait function (above) has | |||
| been called, but for some reason the engine is unable to execute | |||
| a full "cycle". the driver should do whatever is necessary to | |||
| keep itself running correctly, but cannot reference ports | |||
| or other JACK data structures in any way. | |||
| JackDriverNullCycleFunction null_cycle; | |||
| The engine will call this when it plans to stop calling the `wait' | |||
| function for some period of time. the driver should take | |||
| appropriate steps to handle this (possibly no steps at all). | |||
| NOTE: the driver must silence its capture buffers (if any) | |||
| from within this function or the function that actually | |||
| implements the change in state. | |||
| JackDriverStopFunction stop; | |||
| The engine will call this to let the driver know that it plans | |||
| to start calling the `wait' function on a regular basis. the driver | |||
| should take any appropriate steps to handle this (possibly no steps | |||
| at all). NOTE: The driver may wish to silence its playback buffers | |||
| (if any) from within this function or the function that actually | |||
| implements the change in state. | |||
| JackDriverStartFunction start; | |||
| The engine will call this to let the driver know that some client | |||
| has requested a new buffer size. The stop function will be called | |||
| prior to this, and the start function after this one has returned. | |||
| JackDriverBufSizeFunction bufsize; | |||
| */ | |||
| /* define the fields here... */ | |||
| #define JACK_DRIVER_DECL \ | |||
| jack_time_t period_usecs; \ | |||
| jack_time_t last_wait_ust; \ | |||
| void *handle; \ | |||
| struct _jack_client_internal * internal_client; \ | |||
| void (*finish)(struct _jack_driver *);\ | |||
| JackDriverAttachFunction attach; \ | |||
| JackDriverDetachFunction detach; \ | |||
| JackDriverReadFunction read; \ | |||
| JackDriverWriteFunction write; \ | |||
| JackDriverNullCycleFunction null_cycle; \ | |||
| JackDriverStopFunction stop; \ | |||
| JackDriverStartFunction start; \ | |||
| JackDriverBufSizeFunction bufsize; | |||
| JACK_DRIVER_DECL /* expand the macro */ | |||
| } | |||
| jack_driver_t; | |||
| void jack_driver_init (jack_driver_t *); | |||
| void jack_driver_release (jack_driver_t *); | |||
| jack_driver_t *jack_driver_load (int argc, char **argv); | |||
| void jack_driver_unload (jack_driver_t *); | |||
| /**************************** | |||
| *** Non-Threaded Drivers *** | |||
| ****************************/ | |||
| /* | |||
| Call sequence summary: | |||
| 1) engine loads driver via runtime dynamic linking | |||
| - calls jack_driver_load | |||
| - we call dlsym for "driver_initialize" and execute it | |||
| - driver_initialize calls jack_driver_nt_init | |||
| 2) nt layer attaches to driver | |||
| 3) nt layer starts driver | |||
| 4) nt layer runs a thread, calling | |||
| while () { | |||
| driver->nt_run_ctcle(); | |||
| } | |||
| 5) nt layer stops driver | |||
| 6) nt layer detaches driver | |||
| 7) engine calls driver `finish' routine which calls jack_driver_nt_finish | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| struct _jack_driver_nt; | |||
| typedef int (*JackDriverNTAttachFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTDetachFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTStopFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTStartFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTBufSizeFunction)(struct _jack_driver_nt *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverNTRunCycleFunction)(struct _jack_driver_nt *); | |||
| typedef struct _jack_driver_nt | |||
| { | |||
| #define JACK_DRIVER_NT_DECL \ | |||
| JACK_DRIVER_DECL \ | |||
| struct _jack_engine * engine; \ | |||
| volatile int nt_run; \ | |||
| pthread_t nt_thread; \ | |||
| pthread_mutex_t nt_run_lock; \ | |||
| JackDriverNTAttachFunction nt_attach; \ | |||
| JackDriverNTDetachFunction nt_detach; \ | |||
| JackDriverNTStopFunction nt_stop; \ | |||
| JackDriverNTStartFunction nt_start; \ | |||
| JackDriverNTBufSizeFunction nt_bufsize; \ | |||
| JackDriverNTRunCycleFunction nt_run_cycle; | |||
| #define nt_read read | |||
| #define nt_write write | |||
| #define nt_null_cycle null_cycle | |||
| JACK_DRIVER_NT_DECL | |||
| } | |||
| jack_driver_nt_t; | |||
| void jack_driver_nt_init (jack_driver_nt_t * driver); | |||
| void jack_driver_nt_finish (jack_driver_nt_t * driver); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_driver_h__ */ | |||
| @@ -0,0 +1,277 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2004 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __JackIoAudioDriver__ | |||
| #define __JackIoAudioDriver__ | |||
| #include "JackAudioDriver.h" | |||
| #include "JackThreadedDriver.h" | |||
| #include "JackTime.h" | |||
| #include "driver.h" | |||
| #include "memops.h" | |||
| #include <sys/poll.h> | |||
| namespace Jack | |||
| { | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| // CONSTANTS | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| enum IoAudioDriverChannels | |||
| { | |||
| Playback = SND_PCM_CHANNEL_PLAYBACK, | |||
| Capture = SND_PCM_CHANNEL_CAPTURE, | |||
| Extra = SND_PCM_CHANNEL_MAX, | |||
| IoAudioDriverChannels_COUNT | |||
| }; | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| // TYPES | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| // IMPLEMENTATIONS | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| /*! | |||
| \brief The IoAudio driver. | |||
| */ | |||
| class JackIoAudioDriver: public JackAudioDriver | |||
| { | |||
| public: | |||
| typedef void (*ReadCopyFunction)( | |||
| jack_default_audio_sample_t *dst, | |||
| char *src, | |||
| unsigned long src_bytes, | |||
| unsigned long src_skip_bytes ); | |||
| typedef void (*WriteCopyFunction)( | |||
| char *dst, | |||
| jack_default_audio_sample_t *src, | |||
| unsigned long src_bytes, | |||
| unsigned long dst_skip_bytes, | |||
| dither_state_t *state ); | |||
| struct Args | |||
| { | |||
| const char* jack_name; | |||
| const char* jack_alias; | |||
| char* device; | |||
| bool capture; | |||
| const char* capture_pcm_name; | |||
| size_t user_capture_nchnls; | |||
| bool playback; | |||
| const char* playback_pcm_name; | |||
| size_t user_playback_nchnls; | |||
| size_t srate; | |||
| size_t frames_per_interrupt; | |||
| size_t user_nperiods; | |||
| DitherAlgorithm dither; | |||
| bool hw_monitoring; | |||
| bool hw_metering; | |||
| bool duplex; | |||
| bool soft_mode; | |||
| bool monitor; | |||
| bool shorts_first; | |||
| size_t systemic_input_latency; | |||
| size_t systemic_output_latency; | |||
| }; | |||
| struct Voice | |||
| { | |||
| unsigned long interleave_skip; | |||
| char* addr; | |||
| unsigned long silent; | |||
| dither_state_t dither_state; | |||
| }; | |||
| struct Channel | |||
| { | |||
| Voice* voices; | |||
| unsigned int nperiods; | |||
| snd_pcm_t *handle; | |||
| snd_pcm_channel_params_t params; | |||
| snd_pcm_channel_setup_t setup; | |||
| snd_pcm_mmap_control_t *mmap; | |||
| void *mmap_buf; | |||
| void *buffer; | |||
| ReadCopyFunction read; | |||
| WriteCopyFunction write; | |||
| ssize_t sample_bytes() | |||
| { | |||
| return snd_pcm_format_size( setup.format.format, | |||
| 1 ); | |||
| } | |||
| ssize_t frame_bytes() | |||
| { | |||
| return snd_pcm_format_size( setup.format.format, | |||
| setup.format.voices ); | |||
| } | |||
| ssize_t frag_bytes() | |||
| { | |||
| return setup.buf.block.frag_size; | |||
| } | |||
| ssize_t frag_frames() | |||
| { | |||
| return frag_bytes() / frame_bytes(); | |||
| } | |||
| }; | |||
| public: | |||
| JackIoAudioDriver( | |||
| Args args, | |||
| JackLockedEngine* engine, | |||
| JackSynchro* table ); | |||
| virtual ~JackIoAudioDriver(); | |||
| int Attach(); | |||
| int Close(); | |||
| int Detach(); | |||
| // BufferSize can be changed | |||
| bool IsFixedBufferSize() | |||
| { | |||
| return false; | |||
| } | |||
| int Open(); | |||
| int Read(); | |||
| int SetBufferSize( | |||
| jack_nframes_t buffer_size ); | |||
| int Start(); | |||
| int Stop(); | |||
| int Write(); | |||
| private: | |||
| Args fArgs; | |||
| int poll_timeout_msecs; | |||
| jack_time_t poll_last; | |||
| jack_time_t poll_next; | |||
| int poll_late; | |||
| struct pollfd pfd[IoAudioDriverChannels_COUNT]; | |||
| unsigned long interleave_unit; | |||
| unsigned int max_nchannels; | |||
| unsigned int user_nchannels; | |||
| jack_nframes_t frame_rate; | |||
| Channel playback; | |||
| Channel capture; | |||
| jack_hardware_t *hw; | |||
| bool capture_and_playback_not_synced; | |||
| bool has_clock_sync_reporting; | |||
| bool has_hw_monitoring; | |||
| bool do_hw_monitoring; | |||
| unsigned long input_monitor_mask; | |||
| bool has_hw_metering; | |||
| bool do_hw_metering; | |||
| bool quirk_bswap; | |||
| int xrun_count; | |||
| int process_count; | |||
| int in_xrun_recovery; | |||
| int check_capabilities( | |||
| const char *devicename, | |||
| int mode ); | |||
| int check_card_type(); | |||
| void clear_output_aux(); | |||
| int configure_stream( | |||
| const char *device_name, | |||
| const char *stream_name, | |||
| snd_pcm_t *handle, | |||
| snd_pcm_channel_params_t *params, | |||
| unsigned int *nperiodsp ); | |||
| int create( | |||
| jack_client_t *client ); | |||
| int generic_hardware(); | |||
| int get_channel_addresses( | |||
| size_t *capture_avail, | |||
| size_t *playback_avail, | |||
| size_t *capture_offset, | |||
| size_t *playback_offset ); | |||
| int hw_specific(); | |||
| void monitor_input_aux(); | |||
| int read( | |||
| jack_nframes_t nframes ); | |||
| void read_input_aux( | |||
| jack_nframes_t orig_nframes, | |||
| ssize_t contiguous, | |||
| ssize_t nread ); | |||
| int set_parameters(); | |||
| void setup_io_function_pointers(); | |||
| void update_latencies(); | |||
| jack_nframes_t wait( | |||
| int *status, | |||
| float *delayed_usecs ); | |||
| void write_output_aux( | |||
| jack_nframes_t orig_nframes, | |||
| ssize_t contiguous, | |||
| ssize_t nwritten ); | |||
| int xrun_recovery( | |||
| float *delayed_usecs ); | |||
| }; | |||
| } // end of namespace | |||
| #endif | |||
| @@ -0,0 +1,134 @@ | |||
| /* | |||
| * bitset.h -- some simple bit vector set operations. | |||
| * | |||
| * This is useful for sets of small non-negative integers. There are | |||
| * some obvious set operations that are not implemented because I | |||
| * don't need them right now. | |||
| * | |||
| * These functions represent sets as arrays of unsigned 32-bit | |||
| * integers allocated on the heap. The first entry contains the set | |||
| * cardinality (number of elements allowed), followed by one or more | |||
| * words containing bit vectors. | |||
| * | |||
| * $Id: bitset.h,v 1.2 2005/11/23 11:24:29 letz Exp $ | |||
| */ | |||
| /* | |||
| * Copyright (C) 2005 Jack O'Quin | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of the | |||
| * License, or (at your option) any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU General Public License | |||
| * along with this program; if not, write to the Free Software | |||
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __bitset_h__ | |||
| #define __bitset_h__ | |||
| #include <malloc.h> | |||
| #include <string.h> | |||
| #include <inttypes.h> /* POSIX standard fixed-size types */ | |||
| #include <assert.h> /* `#define NDEBUG' to disable */ | |||
| /* On some 64-bit machines, this implementation may be slightly | |||
| * inefficient, depending on how compilers allocate space for | |||
| * uint32_t. For the set sizes I currently need, this is acceptable. | |||
| * It should not be hard to pack the bits better, if that becomes | |||
| * worthwhile. | |||
| */ | |||
| typedef uint32_t _bitset_word_t; | |||
| typedef _bitset_word_t *bitset_t; | |||
| #define WORD_SIZE(cardinality) (1+((cardinality)+31)/32) | |||
| #define BYTE_SIZE(cardinality) (WORD_SIZE(cardinality)*sizeof(_bitset_word_t)) | |||
| #define WORD_INDEX(element) (1+(element)/32) | |||
| #define BIT_INDEX(element) ((element)&037) | |||
| static inline void | |||
| bitset_add(bitset_t set | |||
| , unsigned int element) | |||
| { | |||
| assert(element < set | |||
| [0]); | |||
| set | |||
| [WORD_INDEX(element)] |= (1 << BIT_INDEX(element)); | |||
| } | |||
| static inline void | |||
| bitset_copy(bitset_t to_set, bitset_t from_set) | |||
| { | |||
| assert(to_set[0] == from_set[0]); | |||
| memcpy(to_set, from_set, BYTE_SIZE(to_set[0])); | |||
| } | |||
| static inline void | |||
| bitset_create(bitset_t *set | |||
| , unsigned int cardinality) | |||
| { | |||
| *set | |||
| = (bitset_t) calloc(WORD_SIZE(cardinality), | |||
| sizeof(_bitset_word_t)); | |||
| assert(*set | |||
| ); | |||
| *set | |||
| [0] = cardinality; | |||
| } | |||
| static inline void | |||
| bitset_destroy(bitset_t *set | |||
| ) | |||
| { | |||
| if (*set | |||
| ) { | |||
| free(*set | |||
| ); | |||
| *set | |||
| = (bitset_t) 0; | |||
| } | |||
| } | |||
| static inline int | |||
| bitset_empty(bitset_t set | |||
| ) | |||
| { | |||
| int i; | |||
| _bitset_word_t result = 0; | |||
| int nwords = WORD_SIZE(set | |||
| [0]); | |||
| for (i = 1; i < nwords; i++) { | |||
| result |= set | |||
| [i]; | |||
| } | |||
| return (result == 0); | |||
| } | |||
| static inline int | |||
| bitset_contains(bitset_t set | |||
| , unsigned int element) | |||
| { | |||
| assert(element < set | |||
| [0]); | |||
| return (0 != (set | |||
| [WORD_INDEX(element)] & (1 << BIT_INDEX(element)))); | |||
| } | |||
| static inline void | |||
| bitset_remove(bitset_t set | |||
| , unsigned int element) | |||
| { | |||
| assert(element < set | |||
| [0]); | |||
| set | |||
| [WORD_INDEX(element)] &= ~(1 << BIT_INDEX(element)); | |||
| } | |||
| #endif /* __bitset_h__ */ | |||
| @@ -0,0 +1,76 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| (at your option) any later version. | |||
| This program is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| $Id: hardware.h,v 1.3 2005/11/23 11:24:29 letz Exp $ | |||
| */ | |||
| #ifndef __jack_hardware_h__ | |||
| #define __jack_hardware_h__ | |||
| #include "types.h" | |||
| enum SampleClockMode | |||
| { | |||
| AutoSync, | |||
| WordClock, | |||
| ClockMaster | |||
| }; | |||
| enum Capabilities | |||
| { | |||
| Cap_None = 0x0, | |||
| Cap_HardwareMonitoring = 0x1, | |||
| Cap_AutoSync = 0x2, | |||
| Cap_WordClock = 0x4, | |||
| Cap_ClockMaster = 0x8, | |||
| Cap_ClockLockReporting = 0x10, | |||
| Cap_HardwareMetering = 0x20 | |||
| }; | |||
| struct jack_hardware_t | |||
| { | |||
| Capabilities capabilities; | |||
| unsigned long input_monitor_mask; | |||
| void *private_hw; | |||
| jack_hardware_t() : | |||
| capabilities( Cap_None ), | |||
| input_monitor_mask( 0 ) | |||
| { | |||
| } | |||
| virtual ~jack_hardware_t() {} | |||
| virtual void release() = 0; | |||
| virtual int set_input_monitor_mask( | |||
| unsigned long ) = 0; | |||
| virtual int change_sample_clock( | |||
| SampleClockMode ) = 0; | |||
| virtual double get_hardware_peak( | |||
| jack_port_t *port, | |||
| jack_nframes_t frames ) = 0; | |||
| virtual double get_hardware_power( | |||
| jack_port_t *port, | |||
| jack_nframes_t frames ) = 0; | |||
| }; | |||
| #endif /* __jack_hardware_h__ */ | |||
| @@ -41,3 +41,11 @@ def build(bld): | |||
| deva = create_jack_driver_obj(bld, 'jack', 'ioaudio/ioaudio_driver.c', ['IOAUDIO', 'clientlib', 'PTHREAD']) | |||
| deva.env['cxxshlib_PATTERN'] = 'deva-ctrl-%s.so' | |||
| deva.install_path = '/lib/dll' | |||
| ioaudio_driver_src = [ | |||
| '../common/memops.c', | |||
| #'ioaudio/generic_hw.c', | |||
| #'ioaudio/ioaudio_backend.c', | |||
| 'ioaudio/JackIoAudioDriver.cpp', | |||
| ] | |||
| create_jack_driver_obj(bld, 'ioaudio', ioaudio_driver_src, ['IOAUDIO', 'PTHREAD']) | |||