update wavesaudio backend, now supports Windows (ASIO) as well as OS X (CoreAudio)

This commit is contained in:
Paul Davis 2014-04-29 16:05:54 -04:00
parent 152935e736
commit f374ce69a6
82 changed files with 11259 additions and 7632 deletions

View file

@ -1,127 +1,127 @@
/* pmutil.h -- some helpful utilities for building midi
applications that use PortMidi
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef void PmQueue;
/*
A single-reader, single-writer queue is created by
Pm_QueueCreate(), which takes the number of messages and
the message size as parameters. The queue only accepts
fixed sized messages. Returns NULL if memory cannot be allocated.
This queue implementation uses the "light pipe" algorithm which
operates correctly even with multi-processors and out-of-order
memory writes. (see Alexander Dokumentov, "Lock-free Interprocess
Communication," Dr. Dobbs Portal, http://www.ddj.com/,
articleID=189401457, June 15, 2006. This algorithm requires
that messages be translated to a form where no words contain
zeros. Each word becomes its own "data valid" tag. Because of
this translation, we cannot return a pointer to data still in
the queue when the "peek" method is called. Instead, a buffer
is preallocated so that data can be copied there. Pm_QueuePeek()
dequeues a message into this buffer and returns a pointer to
it. A subsequent Pm_Dequeue() will copy from this buffer.
This implementation does not try to keep reader/writer data in
separate cache lines or prevent thrashing on cache lines.
However, this algorithm differs by doing inserts/removals in
units of messages rather than units of machine words. Some
performance improvement might be obtained by not clearing data
immediately after a read, but instead by waiting for the end
of the cache line, especially if messages are smaller than
cache lines. See the Dokumentov article for explanation.
The algorithm is extended to handle "overflow" reporting. To report
an overflow, the sender writes the current tail position to a field.
The receiver must acknowlege receipt by zeroing the field. The sender
will not send more until the field is zeroed.
Pm_QueueDestroy() destroys the queue and frees its storage.
*/
PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg);
PMEXPORT PmError Pm_QueueDestroy(PmQueue *queue);
/*
Pm_Dequeue() removes one item from the queue, copying it into msg.
Returns 1 if successful, and 0 if the queue is empty.
Returns pmBufferOverflow if what would have been the next thing
in the queue was dropped due to overflow. (So when overflow occurs,
the receiver can receive a queue full of messages before getting the
overflow report. This protocol ensures that the reader will be
notified when data is lost due to overflow.
*/
PMEXPORT PmError Pm_Dequeue(PmQueue *queue, void *msg);
/*
Pm_Enqueue() inserts one item into the queue, copying it from msg.
Returns pmNoError if successful and pmBufferOverflow if the queue was
already full. If pmBufferOverflow is returned, the overflow flag is set.
*/
PMEXPORT PmError Pm_Enqueue(PmQueue *queue, void *msg);
/*
Pm_QueueFull() returns non-zero if the queue is full
Pm_QueueEmpty() returns non-zero if the queue is empty
Either condition may change immediately because a parallel
enqueue or dequeue operation could be in progress. Furthermore,
Pm_QueueEmpty() is optimistic: it may say false, when due to
out-of-order writes, the full message has not arrived. Therefore,
Pm_Dequeue() could still return 0 after Pm_QueueEmpty() returns
false. On the other hand, Pm_QueueFull() is pessimistic: if it
returns false, then Pm_Enqueue() is guaranteed to succeed.
Error conditions: Pm_QueueFull() returns pmBadPtr if queue is NULL.
Pm_QueueEmpty() returns FALSE if queue is NULL.
*/
PMEXPORT int Pm_QueueFull(PmQueue *queue);
PMEXPORT int Pm_QueueEmpty(PmQueue *queue);
/*
Pm_QueuePeek() returns a pointer to the item at the head of the queue,
or NULL if the queue is empty. The item is not removed from the queue.
Pm_QueuePeek() will not indicate when an overflow occurs. If you want
to get and check pmBufferOverflow messages, use the return value of
Pm_QueuePeek() *only* as an indication that you should call
Pm_Dequeue(). At the point where a direct call to Pm_Dequeue() would
return pmBufferOverflow, Pm_QueuePeek() will return NULL but internally
clear the pmBufferOverflow flag, enabling Pm_Enqueue() to resume
enqueuing messages. A subsequent call to Pm_QueuePeek()
will return a pointer to the first message *after* the overflow.
Using this as an indication to call Pm_Dequeue(), the first call
to Pm_Dequeue() will return pmBufferOverflow. The second call will
return success, copying the same message pointed to by the previous
Pm_QueuePeek().
When to use Pm_QueuePeek(): (1) when you need to look at the message
data to decide who should be called to receive it. (2) when you need
to know a message is ready but cannot accept the message.
Note that Pm_QueuePeek() is not a fast check, so if possible, you
might as well just call Pm_Dequeue() and accept the data if it is there.
*/
PMEXPORT void *Pm_QueuePeek(PmQueue *queue);
/*
Pm_SetOverflow() allows the writer (enqueuer) to signal an overflow
condition to the reader (dequeuer). E.g. when transfering data from
the OS to an application, if the OS indicates a buffer overrun,
Pm_SetOverflow() can be used to insure that the reader receives a
pmBufferOverflow result from Pm_Dequeue(). Returns pmBadPtr if queue
is NULL, returns pmBufferOverflow if buffer is already in an overflow
state, returns pmNoError if successfully set overflow state.
*/
PMEXPORT PmError Pm_SetOverflow(PmQueue *queue);
#ifdef __cplusplus
}
#endif /* __cplusplus */
/* pmutil.h -- some helpful utilities for building midi
applications that use PortMidi
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef void PmQueue;
/*
A single-reader, single-writer queue is created by
Pm_QueueCreate(), which takes the number of messages and
the message size as parameters. The queue only accepts
fixed sized messages. Returns NULL if memory cannot be allocated.
This queue implementation uses the "light pipe" algorithm which
operates correctly even with multi-processors and out-of-order
memory writes. (see Alexander Dokumentov, "Lock-free Interprocess
Communication," Dr. Dobbs Portal, http://www.ddj.com/,
articleID=189401457, June 15, 2006. This algorithm requires
that messages be translated to a form where no words contain
zeros. Each word becomes its own "data valid" tag. Because of
this translation, we cannot return a pointer to data still in
the queue when the "peek" method is called. Instead, a buffer
is preallocated so that data can be copied there. Pm_QueuePeek()
dequeues a message into this buffer and returns a pointer to
it. A subsequent Pm_Dequeue() will copy from this buffer.
This implementation does not try to keep reader/writer data in
separate cache lines or prevent thrashing on cache lines.
However, this algorithm differs by doing inserts/removals in
units of messages rather than units of machine words. Some
performance improvement might be obtained by not clearing data
immediately after a read, but instead by waiting for the end
of the cache line, especially if messages are smaller than
cache lines. See the Dokumentov article for explanation.
The algorithm is extended to handle "overflow" reporting. To report
an overflow, the sender writes the current tail position to a field.
The receiver must acknowlege receipt by zeroing the field. The sender
will not send more until the field is zeroed.
Pm_QueueDestroy() destroys the queue and frees its storage.
*/
PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg);
PMEXPORT PmError Pm_QueueDestroy(PmQueue *queue);
/*
Pm_Dequeue() removes one item from the queue, copying it into msg.
Returns 1 if successful, and 0 if the queue is empty.
Returns pmBufferOverflow if what would have been the next thing
in the queue was dropped due to overflow. (So when overflow occurs,
the receiver can receive a queue full of messages before getting the
overflow report. This protocol ensures that the reader will be
notified when data is lost due to overflow.
*/
PMEXPORT PmError Pm_Dequeue(PmQueue *queue, void *msg);
/*
Pm_Enqueue() inserts one item into the queue, copying it from msg.
Returns pmNoError if successful and pmBufferOverflow if the queue was
already full. If pmBufferOverflow is returned, the overflow flag is set.
*/
PMEXPORT PmError Pm_Enqueue(PmQueue *queue, void *msg);
/*
Pm_QueueFull() returns non-zero if the queue is full
Pm_QueueEmpty() returns non-zero if the queue is empty
Either condition may change immediately because a parallel
enqueue or dequeue operation could be in progress. Furthermore,
Pm_QueueEmpty() is optimistic: it may say false, when due to
out-of-order writes, the full message has not arrived. Therefore,
Pm_Dequeue() could still return 0 after Pm_QueueEmpty() returns
false. On the other hand, Pm_QueueFull() is pessimistic: if it
returns false, then Pm_Enqueue() is guaranteed to succeed.
Error conditions: Pm_QueueFull() returns pmBadPtr if queue is NULL.
Pm_QueueEmpty() returns FALSE if queue is NULL.
*/
PMEXPORT int Pm_QueueFull(PmQueue *queue);
PMEXPORT int Pm_QueueEmpty(PmQueue *queue);
/*
Pm_QueuePeek() returns a pointer to the item at the head of the queue,
or NULL if the queue is empty. The item is not removed from the queue.
Pm_QueuePeek() will not indicate when an overflow occurs. If you want
to get and check pmBufferOverflow messages, use the return value of
Pm_QueuePeek() *only* as an indication that you should call
Pm_Dequeue(). At the point where a direct call to Pm_Dequeue() would
return pmBufferOverflow, Pm_QueuePeek() will return NULL but internally
clear the pmBufferOverflow flag, enabling Pm_Enqueue() to resume
enqueuing messages. A subsequent call to Pm_QueuePeek()
will return a pointer to the first message *after* the overflow.
Using this as an indication to call Pm_Dequeue(), the first call
to Pm_Dequeue() will return pmBufferOverflow. The second call will
return success, copying the same message pointed to by the previous
Pm_QueuePeek().
When to use Pm_QueuePeek(): (1) when you need to look at the message
data to decide who should be called to receive it. (2) when you need
to know a message is ready but cannot accept the message.
Note that Pm_QueuePeek() is not a fast check, so if possible, you
might as well just call Pm_Dequeue() and accept the data if it is there.
*/
PMEXPORT void *Pm_QueuePeek(PmQueue *queue);
/*
Pm_SetOverflow() allows the writer (enqueuer) to signal an overflow
condition to the reader (dequeuer). E.g. when transfering data from
the OS to an application, if the OS indicates a buffer overrun,
Pm_SetOverflow() can be used to insure that the reader receives a
pmBufferOverflow result from Pm_Dequeue(). Returns pmBadPtr if queue
is NULL, returns pmBufferOverflow if buffer is already in an overflow
state, returns pmNoError if successfully set overflow state.
*/
PMEXPORT PmError Pm_SetOverflow(PmQueue *queue);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View file

@ -1,178 +1,178 @@
/* pminternal.h -- header for interface implementations */
/* this file is included by files that implement library internals */
/* Here is a guide to implementers:
provide an initialization function similar to pm_winmm_init()
add your initialization function to pm_init()
Note that your init function should never require not-standard
libraries or fail in any way. If the interface is not available,
simply do not call pm_add_device. This means that non-standard
libraries should try to do dynamic linking at runtime using a DLL
and return without error if the DLL cannot be found or if there
is any other failure.
implement functions as indicated in pm_fns_type to open, read, write,
close, etc.
call pm_add_device() for each input and output device, passing it a
pm_fns_type structure.
assumptions about pm_fns_type functions are given below.
*/
#ifdef __cplusplus
extern "C" {
#endif
extern int pm_initialized; /* see note in portmidi.c */
/* these are defined in system-specific file */
void *pm_alloc(size_t s);
void pm_free(void *ptr);
/* if an error occurs while opening or closing a midi stream, set these: */
extern int pm_hosterror;
extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
struct pm_internal_struct;
/* these do not use PmInternal because it is not defined yet... */
typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi,
PmEvent *buffer);
typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
typedef PmError (*pm_end_sysex_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi,
unsigned char byte, PmTimestamp timestamp);
typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi,
PmEvent *buffer);
typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi);
/* pm_open_fn should clean up all memory and close the device if any part
of the open fails */
typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi,
void *driverInfo);
typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi);
/* pm_close_fn should clean up all memory and close the device if any
part of the close fails. */
typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi);
typedef PmError (*pm_poll_fn)(struct pm_internal_struct *midi);
typedef void (*pm_host_error_fn)(struct pm_internal_struct *midi, char * msg,
unsigned int len);
typedef unsigned int (*pm_has_host_error_fn)(struct pm_internal_struct *midi);
typedef struct {
pm_write_short_fn write_short; /* output short MIDI msg */
pm_begin_sysex_fn begin_sysex; /* prepare to send a sysex message */
pm_end_sysex_fn end_sysex; /* marks end of sysex message */
pm_write_byte_fn write_byte; /* accumulate one more sysex byte */
pm_write_realtime_fn write_realtime; /* send real-time message within sysex */
pm_write_flush_fn write_flush; /* send any accumulated but unsent data */
pm_synchronize_fn synchronize; /* synchronize portmidi time to stream time */
pm_open_fn open; /* open MIDI device */
pm_abort_fn abort; /* abort */
pm_close_fn close; /* close device */
pm_poll_fn poll; /* read pending midi events into portmidi buffer */
pm_has_host_error_fn has_host_error; /* true when device has had host
error message */
pm_host_error_fn host_error; /* provide text readable host error message
for device (clears and resets) */
} pm_fns_node, *pm_fns_type;
/* when open fails, the dictionary gets this set of functions: */
extern pm_fns_node pm_none_dictionary;
typedef struct {
PmDeviceInfo pub; /* some portmidi state also saved in here (for autmatic
device closing (see PmDeviceInfo struct) */
void *descriptor; /* ID number passed to win32 multimedia API open */
void *internalDescriptor; /* points to PmInternal device, allows automatic
device closing */
pm_fns_type dictionary;
} descriptor_node, *descriptor_type;
extern int pm_descriptor_max;
extern descriptor_type descriptors;
extern int pm_descriptor_index;
typedef uint32_t (*time_get_proc_type)(void *time_info);
typedef struct pm_internal_struct {
int device_id; /* which device is open (index to descriptors) */
short write_flag; /* MIDI_IN, or MIDI_OUT */
PmTimeProcPtr time_proc; /* where to get the time */
void *time_info; /* pass this to get_time() */
int32_t buffer_len; /* how big is the buffer or queue? */
PmQueue *queue;
int32_t latency; /* time delay in ms between timestamps and actual output */
/* set to zero to get immediate, simple blocking output */
/* if latency is zero, timestamps will be ignored; */
/* if midi input device, this field ignored */
int sysex_in_progress; /* when sysex status is seen, this flag becomes
* true until EOX is seen. When true, new data is appended to the
* stream of outgoing bytes. When overflow occurs, sysex data is
* dropped (until an EOX or non-real-timei status byte is seen) so
* that, if the overflow condition is cleared, we don't start
* sending data from the middle of a sysex message. If a sysex
* message is filtered, sysex_in_progress is false, causing the
* message to be dropped. */
PmMessage sysex_message; /* buffer for 4 bytes of sysex data */
int sysex_message_count; /* how many bytes in sysex_message so far */
int32_t filters; /* flags that filter incoming message classes */
int32_t channel_mask; /* filter incoming messages based on channel */
PmTimestamp last_msg_time; /* timestamp of last message */
PmTimestamp sync_time; /* time of last synchronization */
PmTimestamp now; /* set by PmWrite to current time */
int first_message; /* initially true, used to run first synchronization */
pm_fns_type dictionary; /* implementation functions */
void *descriptor; /* system-dependent state */
/* the following are used to expedite sysex data */
/* on windows, in debug mode, based on some profiling, these optimizations
* cut the time to process sysex bytes from about 7.5 to 0.26 usec/byte,
* but this does not count time in the driver, so I don't know if it is
* important
*/
unsigned char *fill_base; /* addr of ptr to sysex data */
uint32_t *fill_offset_ptr; /* offset of next sysex byte */
int32_t fill_length; /* how many sysex bytes to write */
} PmInternal;
/* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */
void pm_init(void);
void pm_term(void);
/* defined by portMidi, used by pmwinmm */
PmError none_write_short(PmInternal *midi, PmEvent *buffer);
PmError none_write_byte(PmInternal *midi, unsigned char byte,
PmTimestamp timestamp);
PmTimestamp none_synchronize(PmInternal *midi);
PmError pm_fail_fn(PmInternal *midi);
PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp);
PmError pm_success_fn(PmInternal *midi);
PmError pm_add_device(char *interf, char *name, int input, void *descriptor,
pm_fns_type dictionary);
uint32_t pm_read_bytes(PmInternal *midi, const unsigned char *data, int len,
PmTimestamp timestamp);
void pm_read_short(PmInternal *midi, PmEvent *event);
#define none_write_flush pm_fail_timestamp_fn
#define none_sysex pm_fail_timestamp_fn
#define none_poll pm_fail_fn
#define success_poll pm_success_fn
#define MIDI_REALTIME_MASK 0xf8
#define is_real_time(msg) \
((Pm_MessageStatus(msg) & MIDI_REALTIME_MASK) == MIDI_REALTIME_MASK)
int pm_find_default_device(char *pattern, int is_input);
#ifdef __cplusplus
}
#endif
/* pminternal.h -- header for interface implementations */
/* this file is included by files that implement library internals */
/* Here is a guide to implementers:
provide an initialization function similar to pm_winmm_init()
add your initialization function to pm_init()
Note that your init function should never require not-standard
libraries or fail in any way. If the interface is not available,
simply do not call pm_add_device. This means that non-standard
libraries should try to do dynamic linking at runtime using a DLL
and return without error if the DLL cannot be found or if there
is any other failure.
implement functions as indicated in pm_fns_type to open, read, write,
close, etc.
call pm_add_device() for each input and output device, passing it a
pm_fns_type structure.
assumptions about pm_fns_type functions are given below.
*/
#ifdef __cplusplus
extern "C" {
#endif
extern int pm_initialized; /* see note in portmidi.c */
/* these are defined in system-specific file */
void *pm_alloc(size_t s);
void pm_free(void *ptr);
/* if an error occurs while opening or closing a midi stream, set these: */
extern int pm_hosterror;
extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN];
struct pm_internal_struct;
/* these do not use PmInternal because it is not defined yet... */
typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi,
PmEvent *buffer);
typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
typedef PmError (*pm_end_sysex_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi,
unsigned char byte, PmTimestamp timestamp);
typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi,
PmEvent *buffer);
typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi,
PmTimestamp timestamp);
typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi);
/* pm_open_fn should clean up all memory and close the device if any part
of the open fails */
typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi,
void *driverInfo);
typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi);
/* pm_close_fn should clean up all memory and close the device if any
part of the close fails. */
typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi);
typedef PmError (*pm_poll_fn)(struct pm_internal_struct *midi);
typedef void (*pm_host_error_fn)(struct pm_internal_struct *midi, char * msg,
unsigned int len);
typedef unsigned int (*pm_has_host_error_fn)(struct pm_internal_struct *midi);
typedef struct {
pm_write_short_fn write_short; /* output short MIDI msg */
pm_begin_sysex_fn begin_sysex; /* prepare to send a sysex message */
pm_end_sysex_fn end_sysex; /* marks end of sysex message */
pm_write_byte_fn write_byte; /* accumulate one more sysex byte */
pm_write_realtime_fn write_realtime; /* send real-time message within sysex */
pm_write_flush_fn write_flush; /* send any accumulated but unsent data */
pm_synchronize_fn synchronize; /* synchronize portmidi time to stream time */
pm_open_fn open; /* open MIDI device */
pm_abort_fn abort; /* abort */
pm_close_fn close; /* close device */
pm_poll_fn poll; /* read pending midi events into portmidi buffer */
pm_has_host_error_fn has_host_error; /* true when device has had host
error message */
pm_host_error_fn host_error; /* provide text readable host error message
for device (clears and resets) */
} pm_fns_node, *pm_fns_type;
/* when open fails, the dictionary gets this set of functions: */
extern pm_fns_node pm_none_dictionary;
typedef struct {
PmDeviceInfo pub; /* some portmidi state also saved in here (for autmatic
device closing (see PmDeviceInfo struct) */
void *descriptor; /* ID number passed to win32 multimedia API open */
void *internalDescriptor; /* points to PmInternal device, allows automatic
device closing */
pm_fns_type dictionary;
} descriptor_node, *descriptor_type;
extern int pm_descriptor_max;
extern descriptor_type descriptors;
extern int pm_descriptor_index;
typedef uint32_t (*time_get_proc_type)(void *time_info);
typedef struct pm_internal_struct {
int device_id; /* which device is open (index to descriptors) */
short write_flag; /* MIDI_IN, or MIDI_OUT */
PmTimeProcPtr time_proc; /* where to get the time */
void *time_info; /* pass this to get_time() */
int32_t buffer_len; /* how big is the buffer or queue? */
PmQueue *queue;
int32_t latency; /* time delay in ms between timestamps and actual output */
/* set to zero to get immediate, simple blocking output */
/* if latency is zero, timestamps will be ignored; */
/* if midi input device, this field ignored */
int sysex_in_progress; /* when sysex status is seen, this flag becomes
* true until EOX is seen. When true, new data is appended to the
* stream of outgoing bytes. When overflow occurs, sysex data is
* dropped (until an EOX or non-real-timei status byte is seen) so
* that, if the overflow condition is cleared, we don't start
* sending data from the middle of a sysex message. If a sysex
* message is filtered, sysex_in_progress is false, causing the
* message to be dropped. */
PmMessage sysex_message; /* buffer for 4 bytes of sysex data */
int sysex_message_count; /* how many bytes in sysex_message so far */
int32_t filters; /* flags that filter incoming message classes */
int32_t channel_mask; /* filter incoming messages based on channel */
PmTimestamp last_msg_time; /* timestamp of last message */
PmTimestamp sync_time; /* time of last synchronization */
PmTimestamp now; /* set by PmWrite to current time */
int first_message; /* initially true, used to run first synchronization */
pm_fns_type dictionary; /* implementation functions */
void *descriptor; /* system-dependent state */
/* the following are used to expedite sysex data */
/* on windows, in debug mode, based on some profiling, these optimizations
* cut the time to process sysex bytes from about 7.5 to 0.26 usec/byte,
* but this does not count time in the driver, so I don't know if it is
* important
*/
unsigned char *fill_base; /* addr of ptr to sysex data */
uint32_t *fill_offset_ptr; /* offset of next sysex byte */
int32_t fill_length; /* how many sysex bytes to write */
} PmInternal;
/* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */
void pm_init(void);
void pm_term(void);
/* defined by portMidi, used by pmwinmm */
PmError none_write_short(PmInternal *midi, PmEvent *buffer);
PmError none_write_byte(PmInternal *midi, unsigned char byte,
PmTimestamp timestamp);
PmTimestamp none_synchronize(PmInternal *midi);
PmError pm_fail_fn(PmInternal *midi);
PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp);
PmError pm_success_fn(PmInternal *midi);
PmError pm_add_device(char *interf, char *name, int input, void *descriptor,
pm_fns_type dictionary);
uint32_t pm_read_bytes(PmInternal *midi, const unsigned char *data, int len,
PmTimestamp timestamp);
void pm_read_short(PmInternal *midi, PmEvent *event);
#define none_write_flush pm_fail_timestamp_fn
#define none_sysex pm_fail_timestamp_fn
#define none_poll pm_fail_fn
#define success_poll pm_success_fn
#define MIDI_REALTIME_MASK 0xf8
#define is_real_time(msg) \
((Pm_MessageStatus(msg) & MIDI_REALTIME_MASK) == MIDI_REALTIME_MASK)
int pm_find_default_device(char *pattern, int is_input);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,129 @@
# MAKEFILE FOR PORTMIDI
# Roger B. Dannenberg
# Sep 2009
# NOTE: you can use
# make -f pm_osx/Makefile.osx configuration=Release
# to override the default Debug configuration
configuration=Release
PF=/usr/local
# For debugging, define PM_CHECK_ERRORS
ifeq ($(configuration),Release)
CONFIG = Release
else
CONFIG = Debug
endif
current: all
all: $(CONFIG)/CMakeCache.txt
cd $(CONFIG); make
$(CONFIG)/CMakeCache.txt:
rm -f CMakeCache.txt
mkdir -p $(CONFIG)
cd $(CONFIG); cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=$(CONFIG)
**** For instructions: make -f pm_mac\Makefile.osx help ****\n'
help:
echo $$'\n\n\
This is help for portmidi/pm_mac/Makefile.osx\n\n\
Installation path for dylib is $(PF)\n\
To build Release version libraries and test applications,\n \
make -f pm_mac/Makefile.osx\n\
To build Debug version libraries and test applications,\n \
make -f pm_mac/Makefile.osx configuration=Debug\n\
To install universal dynamic library,\n \
sudo make -f pm_mac/Makefile.osx install\n\
To install universal dynamic library with xcode,\n \
make -f pm_mac/Makefile.osx install-with-xcode\n\
To make PmDefaults Java application,\n \
make -f pm_mac/Makefile.osx pmdefaults\n\n \
configuration = $(configuration)\n'
clean:
rm -f *.o *~ core* */*.o */*/*.o */*~ */core* pm_test/*/pm_dll.dll
rm -f *.opt *.ncb *.plg pm_win/Debug/pm_dll.lib pm_win/Release/pm_dll.lib
rm -f pm_test/*.opt pm_test/*.ncb
rm -f pm_java/pmjni/*.o pm_java/pmjni/*~ pm_java/*.h
rm -rf Release/CMakeFiles Debug/CMakeFiles
rm -rf pm_mac/pmdefaults/lib pm_mac/pmdefaults/src
cleaner: clean
rm -rf pm_mac/build
rm -rf pm_mac/Debug pm_mac/Release pm_test/Debug pm_test/Release
rm -f Debug/*.dylib Release/*.dylib
rm -f pm_java/pmjni/Debug/*.jnilib
rm -f pm_java/pmjni/Release/*.jnilib
cleanest: cleaner
rm -f Debug/libportmidi_s.a Release/libportmidi_s.a
rm -f pm_test/Debug/test pm_test/Debug/sysex pm_test/Debug/midithread
rm -f pm_test/Debug/latency pm_test/Debug/midithru
rm -f pm_test/Debug/qtest pm_test/Debug/mm
rm -f pm_test/Release/test pm_test/Release/sysex pm_test/Release/midithread
rm -f pm_test/Release/latency pm_test/Release/midithru
rm -f pm_test/Release/qtest pm_test/Release/mm
rm -f pm_java/*/*.class
rm -f pm_java/pmjni/jportmidi_JPortMidiApi_PortMidiStream.h
backup: cleanest
cd ..; zip -r portmidi.zip portmidi
install: porttime/porttime.h pm_common/portmidi.h \
$(CONFIG)/libportmidi.dylib
install porttime/porttime.h $(PF)/include/
install pm_common/portmidi.h $(PF)/include
install $(CONFIG)/libportmidi.dylib $(PF)/lib/
# note - this uses xcode to build and install portmidi universal binaries
install-with-xcode:
sudo xcodebuild -project pm_mac/pm_mac.xcodeproj \
-configuration Release install DSTROOT=/
##### build pmdefault ######
pm_java/pmjni/jportmidi_JPortMidiApi.h: pm_java/jportmidi/JPortMidiApi.class
cd pm_java; javah jportmidi.JPortMidiApi
mv pm_java/jportmidi_JportMidiApi.h pm_java/pmjni
JAVASRC = pmdefaults/PmDefaultsFrame.java \
pmdefaults/PmDefaults.java \
jportmidi/JPortMidiApi.java jportmidi/JPortMidi.java \
jportmidi/JPortMidiException.java
# this compiles ALL of the java code
pm_java/jportmidi/JPortMidiApi.class: $(JAVASRC:%=pm_java/%)
cd pm_java; javac $(JAVASRC)
$(CONFIG)/libpmjni.dylib:
mkdir -p $(CONFIG)
cd $(CONFIG); make -f ../pm_mac/$(MAKEFILE)
pmdefaults: $(CONFIG)/libpmjni.dylib pm_java/jportmidi/JPortMidiApi.class
ifeq ($(CONFIG),Debug)
echo "Error: you cannot build pmdefaults in a Debug configuration \n\
You should use configuration=Release in the Makefile command line. "
@exit 2
endif
xcodebuild -project pm_mac/pm_mac.xcodeproj \
-configuration Release -target PmDefaults
echo "pmdefaults java application is made"
###### test plist reader #######
PLHDR = pm_mac/readbinaryplist.h
PLSRC = pm_mac/plisttest.c pm_mac/readbinaryplist.c
pm_mac/plisttest: $(PLHDR) $(PLSRC)
cc $(VFLAGS) -Ipm_mac \
-I/Developer/Headers/FlatCarbon \
-I/System/Library/Frameworks/CoreFoundation.framework/Headers \
-I/System/Library/Frameworks/CoreServices.framework/Headers \
$(PLSRC) -o pm_mac/$(CONFIG)/plisttest \
-framework CoreFoundation -framework CoreServices

View file

@ -0,0 +1,163 @@
README_MAC.txt for PortMidi
Roger Dannenberg
20 nov 2009
revised 20 Sep 2010 for Xcode 3.2.4 and CMake 8.2-2
To build PortMidi for Mac OS X, you must install Xcode and
CMake.
CMake can build either command-line Makefiles or Xcode projects.
These approaches are described in separate sections below.
==== CLEANING UP ====
(Skip this for now, but later you might want start from a clean
slate.)
Start in the portmedia/portmidi directory.
make -f pm_mac/Makefile.osx clean
will remove .o, CMakeFiles, and other intermediate files.
Using "cleaner" instead of "clean" will also remove jni-related
intermediate files.
Using "cleanest" instead of "clean" or "cleaner" will also remove
application binaries and the portmidi libraries. (It will not
uninstall anything, however.)
==== USING CMAKE (AND COMMAND LINE TOOLS) ====
Start in the portmedia/portmidi directory.
make -f pm_mac/Makefile.osx
(Begin note: make will invoke cmake to build a Makefile and then make to
build portmidi. This extra level allows you to correctly build
both Release and Debug versions. Release is the default, so to get
the Debug version, use:
make -f pm_mac/Makefile.osx configuration=Debug
)
Release version executables and libraries are now in
portmedia/portmidi/Release
Debug version executables and libraries are created in
portmedia/portmidi/Debug
The Debug versions are compiled with PM_CHECK_ERRORS which
prints an error message and aborts when an error code is returned
by PortMidi functions. This is useful for small command line
applications. Otherwise, you should check and handle error returns
in your program.
You can install portmidi as follows:
cd Release; sudo make install
This will install /usr/local/include/{portmidi.h, porttime.h}
and /usr/local/lib/{libportmidi.dylib, libportmidi_s.a, libpmjni.dylib}
You should now make the pmdefaults.app:
make -f pm_mac/Makefile.osx pmdefaults
NOTE: pmdefaults.app will be in pm_mac/Release/.
Please copy pmdefaults.app to your Applications folder or wherever
you would normally expect to find it.
==== USING CMAKE TO BUILD Xcode PROJECT ====
Before you can use Xcode, you need a portmidi.xcodeproj file.
CMake builds a location-dependent Xcode project, so unfortunately
it is not easy to provide an Xcode project that is ready to use.
Therefore, you should make your own. Once you have it, you can
use it almost like any other Xcode project, and you will not have
to go back to CMake.
(1) Install CMake if you do not have it already.
(2) Open portmedia/portmidi/CMakeLists.txt with CMake
(3) Use Configure and Generate buttons
(4) This creates portmedia/portmidi/portmidi.xcodeproj.
Note: You will also use pm_mac/pm_mac.xcodeproj, which
is not generated by CMake.
(5) Open portmidi/portmidi.xcodeproj with Xcode and
build what you need. The simplest thing is to build the
ALL_BUILD target. The default will be to build the Debug
version, but you may want to change this to Release.
NOTE: ALL_BUILD may report errors. Try simply building again
or rebuilding specific targets that fail until they build
without errors. There appears to be a race condition or
missing dependencies in the build system.
The Debug version is compiled with PM_CHECK_ERRORS, and the
Release version is not. PM_CHECK_ERRORS will print an error
message and exit your program if any error is returned from
a call into PortMidi.
CMake (currently) also creates MinSizRel and RelWithDebInfo
versions, but only because I cannot figure out how to disable
them.
You will probably want the application PmDefaults, which sets
default MIDI In and Out devices for PortMidi. You may also
want to build a Java application using PortMidi. Since I have
not figured out how to use CMake to make an OS X Java application,
use pm_mac/pm_mac.xcodeproj as follows:
(6) open pm_mac/pm_mac.xcodeproj
(7) pm_java/pmjni/portmidi_JportmidiApi.h is needed
by libpmjni.jnilib, the Java native interface library. Since
portmidi_JportmidiApi.h is included with PortMidi, you can skip
to step 8, but if you really want to rebuild everything from
scratch, build the JPortMidiHeaders project first, and continue
with step 8:
(8) If you did not build libpmjni.dylib using portmidi.xcodeproj,
do it now. (It depends on portmidi_JportmidiApi.h, and the
PmDefaults project depends on libpmjni.dylib.)
(9) Returning to pm_mac.xcodeproj, build the PmDefaults program.
(10) If you wish, copy pm_mac/build/Deployment/PmDefaults.app to
your applications folder.
(11) If you want to install libportmidi.dylib, first make it with
Xcode, then
sudo make -f pm_mac/Makefile.osx install
This command will install /usr/local/include/{porttime.h, portmidi.h}
and /usr/local/lib/libportmidi.dylib
Note that the "install" function of xcode creates portmidi/Release
and does not install the library to /usr/local/lib, so please use
the command line installer.
CHANGELOG
20-Sep-2010 Roger B. Dannenberg
Adapted to Xcode 3.2.4
20-Nov-2009 Roger B. Dannenberg
Added some install instructions
26-Sep-2009 Roger B. Dannenberg
More changes for using CMake, Makefiles, XCode
20-Sep-2009 Roger B. Dannenberg
Modifications for using CMake
14-Sep-2009 Roger B. Dannenberg
Modifications for using CMake
17-Jan-2007 Roger B. Dannenberg
Explicit instructions for Xcode
15-Jan-2007 Roger B. Dannenberg
Changed instructions because of changes to Makefile.osx
07-Oct-2006 Roger B. Dannenberg
Added directions for xcodebuild
29-aug-2006 Roger B. Dannenberg
Updated this documentation.

View file

@ -0,0 +1,594 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 44;
objects = {
/* Begin PBXAggregateTarget section */
3D634CAB1247805C0020F829 /* JPortMidiHeaders */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 3D634CAE1247807A0020F829 /* Build configuration list for PBXAggregateTarget "JPortMidiHeaders" */;
buildPhases = (
3D634CAA1247805C0020F829 /* ShellScript */,
);
dependencies = (
3D634CB0124781580020F829 /* PBXTargetDependency */,
);
name = JPortMidiHeaders;
productName = JPortMidiHeaders;
};
3DE2142D124662AA0033C839 /* CopyJavaSources */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 3DE21434124662FF0033C839 /* Build configuration list for PBXAggregateTarget "CopyJavaSources" */;
buildPhases = (
3DE2142C124662AA0033C839 /* CopyFiles */,
);
comments = "The reason for copying files here is that the Compile Java target looks in a particular place for sources. It would be much better to simply have Compile Java look in the original location for all sources, but I don't know how to do that. -RBD\n";
dependencies = (
);
name = CopyJavaSources;
productName = CopyJavaSources;
};
89D0F1C90F3B704E007831A7 /* PmDefaults */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 89D0F1D20F3B7080007831A7 /* Build configuration list for PBXAggregateTarget "PmDefaults" */;
buildPhases = (
);
dependencies = (
89D0F1D10F3B7062007831A7 /* PBXTargetDependency */,
89D0F1CD0F3B7062007831A7 /* PBXTargetDependency */,
3DE21431124662C50033C839 /* PBXTargetDependency */,
);
name = PmDefaults;
productName = pmdefaults;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
3DE2137F124653FB0033C839 /* portmusic_logo.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE2137E124653FB0033C839 /* portmusic_logo.png */; };
3DE21435124663860033C839 /* PmDefaultsFrame.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */; };
3DE214361246638A0033C839 /* PmDefaults.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE2137B1246538B0033C839 /* PmDefaults.java */; };
3DE214371246638F0033C839 /* JPortMidiException.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21382124654DE0033C839 /* JPortMidiException.java */; };
3DE214381246638F0033C839 /* JPortMidiApi.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21381124654CF0033C839 /* JPortMidiApi.java */; };
3DE214391246638F0033C839 /* JPortMidi.java in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DE21380124654BC0033C839 /* JPortMidi.java */; };
3DE216131246AC0E0033C839 /* libpmjni.dylib in Copy Java Resources */ = {isa = PBXBuildFile; fileRef = 3DE216101246ABE30033C839 /* libpmjni.dylib */; };
3DE216951246D57A0033C839 /* pmdefaults.icns in Resources */ = {isa = PBXBuildFile; fileRef = 3DE216901246C6410033C839 /* pmdefaults.icns */; };
89C3F2920F5250A300B0048E /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 89C3F2900F5250A300B0048E /* Credits.rtf */; };
89D0F0240F392F20007831A7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 89D0F0210F392F20007831A7 /* InfoPlist.strings */; };
89D0F0410F39306C007831A7 /* JavaApplicationStub in Copy Executable */ = {isa = PBXBuildFile; fileRef = 89D0F03E0F39304A007831A7 /* JavaApplicationStub */; };
89D0F16A0F3A124E007831A7 /* pmdefaults.jar in Copy Java Resources */ = {isa = PBXBuildFile; fileRef = 89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3D634CAF124781580020F829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 89D0F1C90F3B704E007831A7;
remoteInfo = PmDefaults;
};
3DE21430124662C50033C839 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 3DE2142D124662AA0033C839;
remoteInfo = CopyJavaSources;
};
3DE2145D124666900033C839 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 3DE2142D124662AA0033C839;
remoteInfo = CopyJavaSources;
};
89D0F1CC0F3B7062007831A7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D1107260486CEB800E47090;
remoteInfo = "Assemble Application";
};
89D0F1D00F3B7062007831A7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 89D0F0480F393A6F007831A7;
remoteInfo = "Compile Java";
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
3DE2142C124662AA0033C839 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "${PROJECT_DIR}/pmdefaults/src/java";
dstSubfolderSpec = 0;
files = (
3DE21435124663860033C839 /* PmDefaultsFrame.java in CopyFiles */,
3DE214361246638A0033C839 /* PmDefaults.java in CopyFiles */,
3DE214371246638F0033C839 /* JPortMidiException.java in CopyFiles */,
3DE214381246638F0033C839 /* JPortMidiApi.java in CopyFiles */,
3DE214391246638F0033C839 /* JPortMidi.java in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
89D0F0440F393070007831A7 /* Copy Executable */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 6;
files = (
89D0F0410F39306C007831A7 /* JavaApplicationStub in Copy Executable */,
);
name = "Copy Executable";
runOnlyForDeploymentPostprocessing = 0;
};
89D0F11F0F394189007831A7 /* Copy Java Resources */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 15;
files = (
89D0F16A0F3A124E007831A7 /* pmdefaults.jar in Copy Java Resources */,
3DE216131246AC0E0033C839 /* libpmjni.dylib in Copy Java Resources */,
);
name = "Copy Java Resources";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
3DE2137B1246538B0033C839 /* PmDefaults.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = PmDefaults.java; path = ../pm_java/pmdefaults/PmDefaults.java; sourceTree = SOURCE_ROOT; };
3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = PmDefaultsFrame.java; path = ../pm_java/pmdefaults/PmDefaultsFrame.java; sourceTree = SOURCE_ROOT; };
3DE2137E124653FB0033C839 /* portmusic_logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = portmusic_logo.png; path = ../pm_java/pmdefaults/portmusic_logo.png; sourceTree = SOURCE_ROOT; };
3DE21380124654BC0033C839 /* JPortMidi.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidi.java; path = ../pm_java/jportmidi/JPortMidi.java; sourceTree = SOURCE_ROOT; };
3DE21381124654CF0033C839 /* JPortMidiApi.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidiApi.java; path = ../pm_java/jportmidi/JPortMidiApi.java; sourceTree = SOURCE_ROOT; };
3DE21382124654DE0033C839 /* JPortMidiException.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; name = JPortMidiException.java; path = ../pm_java/jportmidi/JPortMidiException.java; sourceTree = SOURCE_ROOT; };
3DE213841246555A0033C839 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = /System/Library/Frameworks/CoreMIDI.framework; sourceTree = "<absolute>"; };
3DE21390124655760033C839 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
3DE213BE1246557F0033C839 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
3DE216101246ABE30033C839 /* libpmjni.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpmjni.dylib; path = ../Release/libpmjni.dylib; sourceTree = SOURCE_ROOT; };
3DE216901246C6410033C839 /* pmdefaults.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = pmdefaults.icns; path = ../pm_java/pmdefaults/pmdefaults.icns; sourceTree = SOURCE_ROOT; };
89C3F2910F5250A300B0048E /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = "<group>"; };
89D0F0220F392F20007831A7 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
89D0F0230F392F20007831A7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
89D0F03E0F39304A007831A7 /* JavaApplicationStub */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = JavaApplicationStub; path = /System/Library/Frameworks/JavaVM.framework/Versions/A/Resources/MacOS/JavaApplicationStub; sourceTree = "<absolute>"; };
89D0F0840F394066007831A7 /* JavaNativeFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaNativeFoundation.framework; path = /System/Library/Frameworks/JavaVM.framework/Versions/A/Frameworks/JavaNativeFoundation.framework; sourceTree = "<absolute>"; };
89D0F1390F3948A9007831A7 /* pmdefaults/make */ = {isa = PBXFileReference; lastKnownFileType = folder; path = pmdefaults/make; sourceTree = "<group>"; };
89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = pmdefaults.jar; path = build/Release/pmdefaults.jar; sourceTree = SOURCE_ROOT; };
89D0F1860F3A2442007831A7 /* JavaVM.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaVM.framework; path = /System/Library/Frameworks/JavaVM.framework; sourceTree = "<absolute>"; };
8D1107320486CEB800E47090 /* PmDefaults.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PmDefaults.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
3DE213841246555A0033C839 /* CoreMIDI.framework */,
3DE21390124655760033C839 /* CoreFoundation.framework */,
3DE213BE1246557F0033C839 /* CoreAudio.framework */,
89D0F1860F3A2442007831A7 /* JavaVM.framework */,
89D0F0840F394066007831A7 /* JavaNativeFoundation.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
89D0F15D0F3A0FF7007831A7 /* pmdefaults.jar */,
8D1107320486CEB800E47090 /* PmDefaults.app */,
);
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA /* pmdefaults */ = {
isa = PBXGroup;
children = (
3DE216101246ABE30033C839 /* libpmjni.dylib */,
89D0F0260F392F48007831A7 /* Source */,
89D0F0200F392F20007831A7 /* Resources */,
89D0F1390F3948A9007831A7 /* pmdefaults/make */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = pmdefaults;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
3DE2136A124652E20033C839 /* pm_java */ = {
isa = PBXGroup;
children = (
3DE21379124653150033C839 /* pmdefaults */,
3DE2137A1246531D0033C839 /* jportmidi */,
);
name = pm_java;
path = ..;
sourceTree = "<group>";
};
3DE21379124653150033C839 /* pmdefaults */ = {
isa = PBXGroup;
children = (
3DE2137D124653CB0033C839 /* PmDefaultsFrame.java */,
3DE2137B1246538B0033C839 /* PmDefaults.java */,
);
name = pmdefaults;
sourceTree = "<group>";
};
3DE2137A1246531D0033C839 /* jportmidi */ = {
isa = PBXGroup;
children = (
3DE21382124654DE0033C839 /* JPortMidiException.java */,
3DE21381124654CF0033C839 /* JPortMidiApi.java */,
3DE21380124654BC0033C839 /* JPortMidi.java */,
);
name = jportmidi;
sourceTree = "<group>";
};
89D0F0200F392F20007831A7 /* Resources */ = {
isa = PBXGroup;
children = (
3DE216901246C6410033C839 /* pmdefaults.icns */,
3DE2137E124653FB0033C839 /* portmusic_logo.png */,
89C3F2900F5250A300B0048E /* Credits.rtf */,
89D0F0230F392F20007831A7 /* Info.plist */,
89D0F0210F392F20007831A7 /* InfoPlist.strings */,
89D0F03E0F39304A007831A7 /* JavaApplicationStub */,
);
name = Resources;
path = pmdefaults/resources;
sourceTree = "<group>";
};
89D0F0260F392F48007831A7 /* Source */ = {
isa = PBXGroup;
children = (
3DE2136A124652E20033C839 /* pm_java */,
);
name = Source;
path = pmdefaults/src;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
89D0F0480F393A6F007831A7 /* Compile Java */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "-e -f \"${SRCROOT}/make/build.xml\" -debug \"$ACTION\"";
buildConfigurationList = 89D0F04B0F393AB7007831A7 /* Build configuration list for PBXLegacyTarget "Compile Java" */;
buildPhases = (
);
buildToolPath = /usr/bin/ant;
buildWorkingDirectory = "";
dependencies = (
3DE2145E124666900033C839 /* PBXTargetDependency */,
);
name = "Compile Java";
passBuildSettingsInEnvironment = 1;
productName = "Compile Java";
};
/* End PBXLegacyTarget section */
/* Begin PBXNativeTarget section */
8D1107260486CEB800E47090 /* Assemble Application */ = {
isa = PBXNativeTarget;
buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Assemble Application" */;
buildPhases = (
89D0F0440F393070007831A7 /* Copy Executable */,
89D0F11F0F394189007831A7 /* Copy Java Resources */,
8D1107290486CEB800E47090 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Assemble Application";
productInstallPath = "$(HOME)/Applications";
productName = pmdefaults;
productReference = 8D1107320486CEB800E47090 /* PmDefaults.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "pm_mac" */;
compatibilityVersion = "Xcode 3.0";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* pmdefaults */;
projectDirPath = "";
projectRoot = "";
targets = (
3D634CAB1247805C0020F829 /* JPortMidiHeaders */,
89D0F1C90F3B704E007831A7 /* PmDefaults */,
3DE2142D124662AA0033C839 /* CopyJavaSources */,
89D0F0480F393A6F007831A7 /* Compile Java */,
8D1107260486CEB800E47090 /* Assemble Application */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D1107290486CEB800E47090 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3DE216951246D57A0033C839 /* pmdefaults.icns in Resources */,
89D0F0240F392F20007831A7 /* InfoPlist.strings in Resources */,
89C3F2920F5250A300B0048E /* Credits.rtf in Resources */,
3DE2137F124653FB0033C839 /* portmusic_logo.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3D634CAA1247805C0020F829 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo BUILT_PRODUCTS_DIR is ${BUILT_PRODUCTS_DIR}\njavah -classpath \"${BUILT_PRODUCTS_DIR}/pmdefaults.jar\" -force -o \"${BUILT_PRODUCTS_DIR}/jportmidi_JportMidiApi.h\" \"jportmidi.JPortMidiApi\"\nmv \"${BUILT_PRODUCTS_DIR}/jportmidi_JportMidiApi.h\" ../pm_java/pmjni/\necho \"Created ../pm_java/pmjni/jportmidi_JportMidiApi.h\"\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXTargetDependency section */
3D634CB0124781580020F829 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 89D0F1C90F3B704E007831A7 /* PmDefaults */;
targetProxy = 3D634CAF124781580020F829 /* PBXContainerItemProxy */;
};
3DE21431124662C50033C839 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3DE2142D124662AA0033C839 /* CopyJavaSources */;
targetProxy = 3DE21430124662C50033C839 /* PBXContainerItemProxy */;
};
3DE2145E124666900033C839 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3DE2142D124662AA0033C839 /* CopyJavaSources */;
targetProxy = 3DE2145D124666900033C839 /* PBXContainerItemProxy */;
};
89D0F1CD0F3B7062007831A7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D1107260486CEB800E47090 /* Assemble Application */;
targetProxy = 89D0F1CC0F3B7062007831A7 /* PBXContainerItemProxy */;
};
89D0F1D10F3B7062007831A7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 89D0F0480F393A6F007831A7 /* Compile Java */;
targetProxy = 89D0F1D00F3B7062007831A7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
89C3F2900F5250A300B0048E /* Credits.rtf */ = {
isa = PBXVariantGroup;
children = (
89C3F2910F5250A300B0048E /* English */,
);
name = Credits.rtf;
sourceTree = "<group>";
};
89D0F0210F392F20007831A7 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
89D0F0220F392F20007831A7 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
3D634CAC1247805C0020F829 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
PRODUCT_NAME = JPortMidiHeaders;
};
name = Debug;
};
3D634CAD1247805C0020F829 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = JPortMidiHeaders;
ZERO_LINK = NO;
};
name = Release;
};
3DE2142E124662AB0033C839 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
PRODUCT_NAME = CopyJavaSources;
};
name = Debug;
};
3DE2142F124662AB0033C839 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = CopyJavaSources;
ZERO_LINK = NO;
};
name = Release;
};
89D0F0490F393A6F007831A7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = pmdefaults;
SRCROOT = ./pmdefaults;
};
name = Debug;
};
89D0F04A0F393A6F007831A7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = pmdefaults;
SRCROOT = ./pmdefaults;
};
name = Release;
};
89D0F1CA0F3B704F007831A7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = pmdefaults;
};
name = Debug;
};
89D0F1CB0F3B704F007831A7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = pmdefaults;
};
name = Release;
};
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
COPY_PHASE_STRIP = NO;
INFOPLIST_FILE = pmdefaults/resources/Info.plist;
INSTALL_PATH = "$(HOME)/Applications";
PRODUCT_NAME = pmdefaults;
WRAPPER_EXTENSION = app;
};
name = Debug;
};
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
INFOPLIST_FILE = pmdefaults/resources/Info.plist;
INSTALL_PATH = "$(HOME)/Applications";
PRODUCT_NAME = PmDefaults;
WRAPPER_EXTENSION = app;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3D634CAE1247807A0020F829 /* Build configuration list for PBXAggregateTarget "JPortMidiHeaders" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3D634CAC1247805C0020F829 /* Debug */,
3D634CAD1247805C0020F829 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3DE21434124662FF0033C839 /* Build configuration list for PBXAggregateTarget "CopyJavaSources" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3DE2142E124662AB0033C839 /* Debug */,
3DE2142F124662AB0033C839 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
89D0F04B0F393AB7007831A7 /* Build configuration list for PBXLegacyTarget "Compile Java" */ = {
isa = XCConfigurationList;
buildConfigurations = (
89D0F0490F393A6F007831A7 /* Debug */,
89D0F04A0F393A6F007831A7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
89D0F1D20F3B7080007831A7 /* Build configuration list for PBXAggregateTarget "PmDefaults" */ = {
isa = XCConfigurationList;
buildConfigurations = (
89D0F1CA0F3B704F007831A7 /* Debug */,
89D0F1CB0F3B704F007831A7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Assemble Application" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4B08A954540054247B /* Debug */,
C01FCF4C08A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "pm_mac" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:pm_mac.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "89D0F0480F393A6F007831A7"
BuildableName = "Compile Java"
BlueprintName = "Compile Java"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3DE2142D124662AA0033C839"
BuildableName = "CopyJavaSources"
BlueprintName = "CopyJavaSources"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3D634CAB1247805C0020F829"
BuildableName = "JPortMidiHeaders"
BlueprintName = "JPortMidiHeaders"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "89D0F1C90F3B704E007831A7"
BuildableName = "PmDefaults"
BlueprintName = "PmDefaults"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Assemble Application.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
</dict>
<key>Compile Java.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
<key>CopyJavaSources.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>JPortMidiHeaders.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>PmDefaults.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>3D634CAB1247805C0020F829</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>3DE2142D124662AA0033C839</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>89D0F0480F393A6F007831A7</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>89D0F1C90F3B704E007831A7</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>8D1107260486CEB800E47090</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D1107260486CEB800E47090"
BuildableName = "PmDefaults.app"
BlueprintName = "Assemble Application"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "89D0F0480F393A6F007831A7"
BuildableName = "Compile Java"
BlueprintName = "Compile Java"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3DE2142D124662AA0033C839"
BuildableName = "CopyJavaSources"
BlueprintName = "CopyJavaSources"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3D634CAB1247805C0020F829"
BuildableName = "JPortMidiHeaders"
BlueprintName = "JPortMidiHeaders"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0460"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "89D0F1C90F3B704E007831A7"
BuildableName = "PmDefaults"
BlueprintName = "PmDefaults"
ReferencedContainer = "container:pm_mac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Assemble Application.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
</dict>
<key>Compile Java.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
</dict>
<key>CopyJavaSources.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
<key>JPortMidiHeaders.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
<key>PmDefaults.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>3D634CAB1247805C0020F829</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>3DE2142D124662AA0033C839</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>89D0F0480F393A6F007831A7</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>89D0F1C90F3B704E007831A7</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>8D1107260486CEB800E47090</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="pmdefaults" default="jar" basedir="..">
<!-- Global Properties -->
<property environment="env"/>
<!-- building in Xcode -->
<condition property="product" value="${env.PRODUCT_NAME}">
<isset property="env.PRODUCT_NAME"/>
</condition>
<condition property="src" value="${env.SRCROOT}/src">
<isset property="env.SRCROOT"/>
</condition>
<condition property="obj" value="${env.OBJECT_FILE_DIR}">
<isset property="env.OBJECT_FILE_DIR"/>
</condition>
<condition property="dst" value="${env.BUILT_PRODUCTS_DIR}">
<isset property="env.BUILT_PRODUCTS_DIR"/>
</condition>
<!-- building from the command line -->
<condition property="src" value="src">
<not>
<isset property="src"/>
</not>
</condition>
<condition property="obj" value="build/obj">
<not>
<isset property="obj"/>
</not>
</condition>
<condition property="dst" value="build">
<not>
<isset property="dst"/>
</not>
</condition>
<condition property="product" value="pmdefaults">
<not>
<isset property="product"/>
</not>
</condition>
<!-- Targets -->
<target name="init" description="Create build directories">
<mkdir dir="${obj}/${product}"/>
<mkdir dir="${dst}"/>
</target>
<target name="compile" depends="init" description="Compile">
<javac destdir="${obj}/${product}" deprecation="on" source="1.5" target="1.5" fork="true" debug="true" debuglevel="lines,source">
<src path="${src}/java"/>
<classpath path="${src}/../lib/eawt-stubs.jar"/>
</javac>
</target>
<target name="copy" depends="init" description="Copy resources">
</target>
<target name="jar" depends="compile, copy" description="Assemble Jar file">
<jar jarfile="${dst}/${product}.jar" basedir="${obj}/${product}" manifest="resources/Manifest" index="true"/>
</target>
<target name="install" depends="jar" description="Alias for 'jar'">
<!-- sent by Xcode -->
</target>
<target name="clean" description="Removes build directories">
<!-- sent by Xcode -->
<delete dir="${obj}/${product}"/>
<delete file="${dst}/${product}.jar"/>
</target>
<target name="installhdrs" description="">
<!-- sent by Xcode -->
<echo>"Nothing to do for install-headers phase"</echo>
</target>
</project>

View file

@ -0,0 +1,31 @@
#!/bin/sh
# Prints all class references made by all classes in a Jar file
# Depends on the output formatting of javap
# create a temporary working directory
dir=`mktemp -d $TMPDIR/classrefs.XXXXXX`
asm_dump="$dir/asm_dump"
all_classes="$dir/all_classes"
# for each class in a Jar file, dump the full assembly
javap -c -classpath "$1" `/usr/bin/jar tf "$1" | grep "\.class" | sort | xargs | sed -e 's/\.class//g'` > $asm_dump
# dump the initial list of all classes in the Jar file
/usr/bin/jar tf $1 | grep "\.class" | sed -e 's/\.class//g' >> $all_classes
# dump all static class references
cat $asm_dump | grep //class | awk -F"//class " '{print $2}' | sort | uniq >> $all_classes
# dump all references to classes made in methods
cat $asm_dump | grep //Method | awk -F"//Method " '{print $2}' | sort | uniq | grep "\." | awk -F"." '{print $1}' | sort | uniq >> $all_classes
# dump all references to classes by direct field access
cat $asm_dump | grep //Field | awk -F"//Field " '{print $2}' | sort | uniq | grep "\:L" | awk -F"\:L" '{print $2}' | sort | uniq | awk -F"\;" '{print $1}' >> $all_classes
# sort and reformat
sort $all_classes | uniq | grep -v "\"" | sed -e 's/\//\./g'
# cleanup
rm -rf $dir

View file

@ -0,0 +1,14 @@
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\b\fs24 \cf0 Author:
\b0 \
Roger B. Dannenberg\
\
\b With special thanks to:
\b0 \
National Science Foundation\
}

View file

@ -0,0 +1,3 @@
/* Localized versions of Info.plist keys */
NSHumanReadableCopyright = "© Carnegie Mellon University, 2010";

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>JavaApplicationStub</string>
<key>CFBundleIconFile</key>
<string>pmdefaults.icns</string>
<key>CFBundleIdentifier</key>
<string></string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>PmDefaults</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>Java</key>
<dict>
<key>ClassPath</key>
<string>$JAVAROOT/pmdefaults.jar</string>
<key>JVMVersion</key>
<string>1.5+</string>
<key>MainClass</key>
<string>pmdefaults.PmDefaults</string>
<key>Properties</key>
<dict>
<key>apple.laf.useScreenMenuBar</key>
<string>true</string>
</dict>
</dict>
</dict>
</plist>

View file

@ -0,0 +1 @@
Main-Class: pmdefaults/PmDefaults

View file

@ -1,59 +1,59 @@
/* pmmac.c -- PortMidi os-dependent code */
/* This file only needs to implement:
pm_init(), which calls various routines to register the
available midi devices,
Pm_GetDefaultInputDeviceID(), and
Pm_GetDefaultOutputDeviceID().
It is seperate from pmmacosxcm because we might want to register
non-CoreMIDI devices.
*/
#include "stdlib.h"
#include "portmidi.h"
#include "pmutil.h"
#include "pminternal.h"
#include "pmmacosxcm.h"
PmDeviceID pm_default_input_device_id = -1;
PmDeviceID pm_default_output_device_id = -1;
void pm_init()
{
PmError err = pm_macosxcm_init();
// this is set when we return to Pm_Initialize, but we need it
// now in order to (successfully) call Pm_CountDevices()
pm_initialized = TRUE;
if (!err) {
pm_default_input_device_id = find_default_device(
"/PortMidi/PM_RECOMMENDED_INPUT_DEVICE", TRUE,
pm_default_input_device_id);
pm_default_output_device_id = find_default_device(
"/PortMidi/PM_RECOMMENDED_OUTPUT_DEVICE", FALSE,
pm_default_output_device_id);
}
}
void pm_term(void)
{
pm_macosxcm_term();
}
PmDeviceID Pm_GetDefaultInputDeviceID()
{
Pm_Initialize();
return pm_default_input_device_id;
}
PmDeviceID Pm_GetDefaultOutputDeviceID() {
Pm_Initialize();
return pm_default_output_device_id;
}
void *pm_alloc(size_t s) { return malloc(s); }
void pm_free(void *ptr) { free(ptr); }
/* pmmac.c -- PortMidi os-dependent code */
/* This file only needs to implement:
pm_init(), which calls various routines to register the
available midi devices,
Pm_GetDefaultInputDeviceID(), and
Pm_GetDefaultOutputDeviceID().
It is seperate from pmmacosxcm because we might want to register
non-CoreMIDI devices.
*/
#include "stdlib.h"
#include "portmidi.h"
#include "pmutil.h"
#include "pminternal.h"
#include "pmmacosxcm.h"
PmDeviceID pm_default_input_device_id = -1;
PmDeviceID pm_default_output_device_id = -1;
void pm_init()
{
PmError err = pm_macosxcm_init();
// this is set when we return to Pm_Initialize, but we need it
// now in order to (successfully) call Pm_CountDevices()
pm_initialized = TRUE;
if (!err) {
pm_default_input_device_id = find_default_device(
"/PortMidi/PM_RECOMMENDED_INPUT_DEVICE", TRUE,
pm_default_input_device_id);
pm_default_output_device_id = find_default_device(
"/PortMidi/PM_RECOMMENDED_OUTPUT_DEVICE", FALSE,
pm_default_output_device_id);
}
}
void pm_term(void)
{
pm_macosxcm_term();
}
PmDeviceID Pm_GetDefaultInputDeviceID()
{
Pm_Initialize();
return pm_default_input_device_id;
}
PmDeviceID Pm_GetDefaultOutputDeviceID() {
Pm_Initialize();
return pm_default_output_device_id;
}
void *pm_alloc(size_t s) { return malloc(s); }
void pm_free(void *ptr) { free(ptr); }

View file

@ -1,4 +1,4 @@
/* pmmac.h */
extern PmDeviceID pm_default_input_device_id;
/* pmmac.h */
extern PmDeviceID pm_default_input_device_id;
extern PmDeviceID pm_default_output_device_id;

View file

@ -1,6 +1,6 @@
/* system-specific definitions */
PmError pm_macosxcm_init(void);
void pm_macosxcm_term(void);
PmDeviceID find_default_device(char *path, int input, PmDeviceID id);
/* system-specific definitions */
PmError pm_macosxcm_init(void);
void pm_macosxcm_term(void);
PmDeviceID find_default_device(char *path, int input, PmDeviceID id);

File diff suppressed because it is too large Load diff

View file

@ -1,143 +1,143 @@
/* pmwin.c -- PortMidi os-dependent code */
/* This file only needs to implement:
pm_init(), which calls various routines to register the
available midi devices,
Pm_GetDefaultInputDeviceID(), and
Pm_GetDefaultOutputDeviceID().
This file must
be separate from the main portmidi.c file because it is system
dependent, and it is separate from, say, pmwinmm.c, because it
might need to register devices for winmm, directx, and others.
*/
#include "stdlib.h"
#include "portmidi.h"
#include "pmutil.h"
#include "pminternal.h"
#include "pmwinmm.h"
#ifdef DEBUG
#include "stdio.h"
#endif
#include <windows.h>
/* pm_exit is called when the program exits.
It calls pm_term to make sure PortMidi is properly closed.
If DEBUG is on, we prompt for input to avoid losing error messages.
*/
static void pm_exit(void) {
pm_term();
#ifdef DEBUG
#define STRING_MAX 80
{
char line[STRING_MAX];
printf("Type ENTER...\n");
/* note, w/o this prompting, client console application can not see one
of its errors before closing. */
fgets(line, STRING_MAX, stdin);
}
#endif
}
/* pm_init is the windows-dependent initialization.*/
void pm_init(void)
{
atexit(pm_exit);
#ifdef DEBUG
printf("registered pm_exit with atexit()\n");
#endif
pm_winmm_init();
/* initialize other APIs (DirectX?) here */
}
void pm_term(void) {
pm_winmm_term();
}
static PmDeviceID pm_get_default_device_id(int is_input, char *key) {
HKEY hkey;
#define PATTERN_MAX 256
char pattern[PATTERN_MAX];
long pattern_max = PATTERN_MAX;
DWORD dwType;
/* Find first input or device -- this is the default. */
PmDeviceID id = pmNoDevice;
int i, j;
Pm_Initialize(); /* make sure descriptors exist! */
for (i = 0; i < pm_descriptor_index; i++) {
if (descriptors[i].pub.input == is_input) {
id = i;
break;
}
}
/* Look in registry for a default device name pattern. */
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegOpenKeyEx(hkey, "JavaSoft", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegOpenKeyEx(hkey, "Prefs", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegOpenKeyEx(hkey, "/Port/Midi", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegQueryValueEx(hkey, key, NULL, &dwType, pattern, &pattern_max) !=
ERROR_SUCCESS) {
return id;
}
/* decode pattern: upper case encoded with "/" prefix */
i = j = 0;
while (pattern[i]) {
if (pattern[i] == '/' && pattern[i + 1]) {
pattern[j++] = toupper(pattern[++i]);
} else {
pattern[j++] = tolower(pattern[i]);
}
i++;
}
pattern[j] = 0; /* end of string */
/* now pattern is the string from the registry; search for match */
i = pm_find_default_device(pattern, is_input);
if (i != pmNoDevice) {
id = i;
}
return id;
}
PmDeviceID Pm_GetDefaultInputDeviceID() {
return pm_get_default_device_id(TRUE,
"/P/M_/R/E/C/O/M/M/E/N/D/E/D_/I/N/P/U/T_/D/E/V/I/C/E");
}
PmDeviceID Pm_GetDefaultOutputDeviceID() {
return pm_get_default_device_id(FALSE,
"/P/M_/R/E/C/O/M/M/E/N/D/E/D_/O/U/T/P/U/T_/D/E/V/I/C/E");
}
#include "stdio.h"
void *pm_alloc(size_t s) {
return malloc(s);
}
void pm_free(void *ptr) {
free(ptr);
}
/* pmwin.c -- PortMidi os-dependent code */
/* This file only needs to implement:
pm_init(), which calls various routines to register the
available midi devices,
Pm_GetDefaultInputDeviceID(), and
Pm_GetDefaultOutputDeviceID().
This file must
be separate from the main portmidi.c file because it is system
dependent, and it is separate from, say, pmwinmm.c, because it
might need to register devices for winmm, directx, and others.
*/
#include "stdlib.h"
#include "portmidi.h"
#include "pmutil.h"
#include "pminternal.h"
#include "pmwinmm.h"
#ifdef DEBUG
#include "stdio.h"
#endif
#include <windows.h>
/* pm_exit is called when the program exits.
It calls pm_term to make sure PortMidi is properly closed.
If DEBUG is on, we prompt for input to avoid losing error messages.
*/
static void pm_exit(void) {
pm_term();
#ifdef DEBUG
#define STRING_MAX 80
{
char line[STRING_MAX];
printf("Type ENTER...\n");
/* note, w/o this prompting, client console application can not see one
of its errors before closing. */
fgets(line, STRING_MAX, stdin);
}
#endif
}
/* pm_init is the windows-dependent initialization.*/
void pm_init(void)
{
atexit(pm_exit);
#ifdef DEBUG
printf("registered pm_exit with atexit()\n");
#endif
pm_winmm_init();
/* initialize other APIs (DirectX?) here */
}
void pm_term(void) {
pm_winmm_term();
}
static PmDeviceID pm_get_default_device_id(int is_input, char *key) {
HKEY hkey;
#define PATTERN_MAX 256
char pattern[PATTERN_MAX];
long pattern_max = PATTERN_MAX;
DWORD dwType;
/* Find first input or device -- this is the default. */
PmDeviceID id = pmNoDevice;
int i, j;
Pm_Initialize(); /* make sure descriptors exist! */
for (i = 0; i < pm_descriptor_index; i++) {
if (descriptors[i].pub.input == is_input) {
id = i;
break;
}
}
/* Look in registry for a default device name pattern. */
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegOpenKeyEx(hkey, "JavaSoft", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegOpenKeyEx(hkey, "Prefs", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegOpenKeyEx(hkey, "/Port/Midi", 0, KEY_READ, &hkey) !=
ERROR_SUCCESS) {
return id;
}
if (RegQueryValueEx(hkey, key, NULL, &dwType, pattern, &pattern_max) !=
ERROR_SUCCESS) {
return id;
}
/* decode pattern: upper case encoded with "/" prefix */
i = j = 0;
while (pattern[i]) {
if (pattern[i] == '/' && pattern[i + 1]) {
pattern[j++] = toupper(pattern[++i]);
} else {
pattern[j++] = tolower(pattern[i]);
}
i++;
}
pattern[j] = 0; /* end of string */
/* now pattern is the string from the registry; search for match */
i = pm_find_default_device(pattern, is_input);
if (i != pmNoDevice) {
id = i;
}
return id;
}
PmDeviceID Pm_GetDefaultInputDeviceID() {
return pm_get_default_device_id(TRUE,
"/P/M_/R/E/C/O/M/M/E/N/D/E/D_/I/N/P/U/T_/D/E/V/I/C/E");
}
PmDeviceID Pm_GetDefaultOutputDeviceID() {
return pm_get_default_device_id(FALSE,
"/P/M_/R/E/C/O/M/M/E/N/D/E/D_/O/U/T/P/U/T_/D/E/V/I/C/E");
}
#include "stdio.h"
void *pm_alloc(size_t s) {
return malloc(s);
}
void pm_free(void *ptr) {
free(ptr);
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* midiwin32.h -- system-specific definitions */
void pm_winmm_init( void );
void pm_winmm_term( void );
/* midiwin32.h -- system-specific definitions */
void pm_winmm_init( void );
void pm_winmm_term( void );

View file

@ -1,131 +1,131 @@
/* ptmacosx.c -- portable timer implementation for mac os x */
#include <stdlib.h>
#include <stdio.h>
#include <CoreAudio/HostTime.h>
#import <mach/mach.h>
#import <mach/mach_error.h>
#import <mach/mach_time.h>
#import <mach/clock.h>
#include <unistd.h>
#include "porttime.h"
#include "sys/time.h"
#include "pthread.h"
#define NSEC_PER_MSEC 1000000
#define THREAD_IMPORTANCE 30
static int time_started_flag = FALSE;
static UInt64 start_time;
static pthread_t pt_thread_pid;
/* note that this is static data -- we only need one copy */
typedef struct {
int id;
int resolution;
PtCallback *callback;
void *userData;
} pt_callback_parameters;
static int pt_callback_proc_id = 0;
static void *Pt_CallbackProc(void *p)
{
pt_callback_parameters *parameters = (pt_callback_parameters *) p;
int mytime = 1;
kern_return_t error;
thread_extended_policy_data_t extendedPolicy;
thread_precedence_policy_data_t precedencePolicy;
extendedPolicy.timeshare = 0;
error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
(thread_policy_t)&extendedPolicy,
THREAD_EXTENDED_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread timeshare policy", error);
}
precedencePolicy.importance = THREAD_IMPORTANCE;
error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
(thread_policy_t)&precedencePolicy,
THREAD_PRECEDENCE_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread precedence policy", error);
}
/* to kill a process, just increment the pt_callback_proc_id */
/* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); */
while (pt_callback_proc_id == parameters->id) {
/* wait for a multiple of resolution ms */
UInt64 wait_time;
int delay = mytime++ * parameters->resolution - Pt_Time();
PtTimestamp timestamp;
if (delay < 0) delay = 0;
wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC);
wait_time += AudioGetCurrentHostTime();
error = mach_wait_until(wait_time);
timestamp = Pt_Time();
(*(parameters->callback))(timestamp, parameters->userData);
}
free(parameters);
return NULL;
}
PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
if (time_started_flag) return ptAlreadyStarted;
start_time = AudioGetCurrentHostTime();
if (callback) {
int res;
pt_callback_parameters *parms;
parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters));
if (!parms) return ptInsufficientMemory;
parms->id = pt_callback_proc_id;
parms->resolution = resolution;
parms->callback = callback;
parms->userData = userData;
res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms);
if (res != 0) return ptHostError;
}
time_started_flag = TRUE;
return ptNoError;
}
PtError Pt_Stop()
{
/* printf("Pt_Stop called\n"); */
pt_callback_proc_id++;
pthread_join(pt_thread_pid, NULL);
time_started_flag = FALSE;
return ptNoError;
}
int Pt_Started()
{
return time_started_flag;
}
PtTimestamp Pt_Time()
{
UInt64 clock_time, nsec_time;
clock_time = AudioGetCurrentHostTime() - start_time;
nsec_time = AudioConvertHostTimeToNanos(clock_time);
return (PtTimestamp)(nsec_time / NSEC_PER_MSEC);
}
void Pt_Sleep(int32_t duration)
{
usleep(duration * 1000);
}
/* ptmacosx.c -- portable timer implementation for mac os x */
#include <stdlib.h>
#include <stdio.h>
#include <CoreAudio/HostTime.h>
#import <mach/mach.h>
#import <mach/mach_error.h>
#import <mach/mach_time.h>
#import <mach/clock.h>
#include <unistd.h>
#include "porttime.h"
#include "sys/time.h"
#include "pthread.h"
#define NSEC_PER_MSEC 1000000
#define THREAD_IMPORTANCE 30
static int time_started_flag = FALSE;
static UInt64 start_time;
static pthread_t pt_thread_pid;
/* note that this is static data -- we only need one copy */
typedef struct {
int id;
int resolution;
PtCallback *callback;
void *userData;
} pt_callback_parameters;
static int pt_callback_proc_id = 0;
static void *Pt_CallbackProc(void *p)
{
pt_callback_parameters *parameters = (pt_callback_parameters *) p;
int mytime = 1;
kern_return_t error;
thread_extended_policy_data_t extendedPolicy;
thread_precedence_policy_data_t precedencePolicy;
extendedPolicy.timeshare = 0;
error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
(thread_policy_t)&extendedPolicy,
THREAD_EXTENDED_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread timeshare policy", error);
}
precedencePolicy.importance = THREAD_IMPORTANCE;
error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
(thread_policy_t)&precedencePolicy,
THREAD_PRECEDENCE_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread precedence policy", error);
}
/* to kill a process, just increment the pt_callback_proc_id */
/* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); */
while (pt_callback_proc_id == parameters->id) {
/* wait for a multiple of resolution ms */
UInt64 wait_time;
int delay = mytime++ * parameters->resolution - Pt_Time();
PtTimestamp timestamp;
if (delay < 0) delay = 0;
wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC);
wait_time += AudioGetCurrentHostTime();
error = mach_wait_until(wait_time);
timestamp = Pt_Time();
(*(parameters->callback))(timestamp, parameters->userData);
}
free(parameters);
return NULL;
}
PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
if (time_started_flag) return ptAlreadyStarted;
start_time = AudioGetCurrentHostTime();
if (callback) {
int res;
pt_callback_parameters *parms;
parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters));
if (!parms) return ptInsufficientMemory;
parms->id = pt_callback_proc_id;
parms->resolution = resolution;
parms->callback = callback;
parms->userData = userData;
res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms);
if (res != 0) return ptHostError;
}
time_started_flag = TRUE;
return ptNoError;
}
PtError Pt_Stop()
{
/* printf("Pt_Stop called\n"); */
pt_callback_proc_id++;
pthread_join(pt_thread_pid, NULL);
time_started_flag = FALSE;
return ptNoError;
}
int Pt_Started()
{
return time_started_flag;
}
PtTimestamp Pt_Time()
{
UInt64 clock_time, nsec_time;
clock_time = AudioGetCurrentHostTime() - start_time;
nsec_time = AudioConvertHostTimeToNanos(clock_time);
return (PtTimestamp)(nsec_time / NSEC_PER_MSEC);
}
void Pt_Sleep(int32_t duration)
{
usleep(duration * 1000);
}

View file

@ -0,0 +1,70 @@
/* ptwinmm.c -- portable timer implementation for win32 */
#include "porttime.h"
#include "windows.h"
#include "time.h"
TIMECAPS caps;
static long time_offset = 0;
static int time_started_flag = FALSE;
static long time_resolution;
static MMRESULT timer_id;
static PtCallback *time_callback;
void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD_PTR dwUser,
DWORD_PTR dw1, DWORD_PTR dw2)
{
(*time_callback)(Pt_Time(), (void *) dwUser);
}
PMEXPORT PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
if (time_started_flag) return ptAlreadyStarted;
timeBeginPeriod(resolution);
time_resolution = resolution;
time_offset = timeGetTime();
time_started_flag = TRUE;
time_callback = callback;
if (callback) {
timer_id = timeSetEvent(resolution, 1, winmm_time_callback,
(DWORD_PTR) userData, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
if (!timer_id) return ptHostError;
}
return ptNoError;
}
PMEXPORT PtError Pt_Stop()
{
if (!time_started_flag) return ptAlreadyStopped;
if (time_callback && timer_id) {
timeKillEvent(timer_id);
time_callback = NULL;
timer_id = 0;
}
time_started_flag = FALSE;
timeEndPeriod(time_resolution);
return ptNoError;
}
PMEXPORT int Pt_Started()
{
return time_started_flag;
}
PMEXPORT PtTimestamp Pt_Time()
{
return timeGetTime() - time_offset;
}
PMEXPORT void Pt_Sleep(int32_t duration)
{
Sleep(duration);
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
Copyright (C) 2013 Valeriy Kamyshniy
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
@ -41,7 +41,7 @@
class ArdourAudioDeviceManager : public WCMRCoreAudioDeviceManager
{
public:
ArdourAudioDeviceManager (WCMRAudioDeviceManagerClient *client) : WCMRCoreAudioDeviceManager (client, eFullDuplexDevices, true, eCABS_Simple, false) {};
ArdourAudioDeviceManager (WCMRAudioDeviceManagerClient *client) : WCMRCoreAudioDeviceManager (client, eAllDevices) {};
};
#elif defined (_WINDOWS)
@ -51,7 +51,7 @@ class ArdourAudioDeviceManager : public WCMRCoreAudioDeviceManager
class ArdourAudioDeviceManager : public WCMRPortAudioDeviceManager
{
public:
ArdourAudioDeviceManager (WCMRAudioDeviceManagerClient *client) : WCMRPortAudioDeviceManager (client, eFullDuplexDevices, paASIO) {};
ArdourAudioDeviceManager (WCMRAudioDeviceManagerClient *client) : WCMRPortAudioDeviceManager (client, eAllDevices) {};
};
#endif
@ -103,10 +103,14 @@ class WavesMidiPort;
virtual int set_device_name (const std::string& name);
virtual int drop_device();
virtual int set_sample_rate (float);
virtual int set_buffer_size (uint32_t);
virtual int set_sample_format (SampleFormat);
virtual int set_interleaved (bool yn);
virtual int set_input_channels (uint32_t);
@ -123,6 +127,8 @@ class WavesMidiPort;
virtual uint32_t buffer_size () const;
virtual SampleFormat sample_format () const;
virtual bool interleaved () const;
virtual uint32_t input_channels () const;
@ -275,6 +281,7 @@ class WavesMidiPort;
WavesMidiDeviceManager _midi_device_manager;
WCMRAudioDevice *_device;
SampleFormat _sample_format;
bool _interleaved;
static std::string __instantiated_name;
uint32_t _input_channels;
@ -317,8 +324,15 @@ class WavesMidiPort;
pframes_t sample_time,
uint64_t cycle_start_time_nanos);
int _reset_device (uint32_t buffer_size, float sample_rate);
void _changed_midi_devices ();
// DO change sample rate and buffer size
int _buffer_size_change(uint32_t new_buffer_size);
int _sample_rate_change(float new_sample_rate);
int _device_list_change();
int _register_system_audio_ports ();
int _register_system_midi_ports ();

View file

@ -1,90 +1,90 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include "waves_dataport.h"
#include "waves_audiobackend.h"
using namespace ARDOUR;
int
WavesAudioBackend::set_systemic_input_latency (uint32_t systemic_input_latency)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_systemic_input_latency (): " << systemic_input_latency << std::endl;
_systemic_input_latency = systemic_input_latency;
return 0;
}
int
WavesAudioBackend::set_systemic_output_latency (uint32_t systemic_output_latency)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_systemic_output_latency (): " << systemic_output_latency << std::endl;
_systemic_output_latency = systemic_output_latency;
return 0;
}
uint32_t
WavesAudioBackend::systemic_input_latency () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::systemic_input_latency ()" << std::endl;
return _systemic_input_latency;
}
uint32_t
WavesAudioBackend::systemic_output_latency () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::systemic_output_latency ()" << std::endl;
return _systemic_output_latency;
}
void
WavesAudioBackend::update_latencies ()
{
// COMMENTED DBG LOGS */ std::cout << "update_latencies:" << std::endl;
}
void
WavesAudioBackend::set_latency_range (PortHandle port_handle, bool for_playback, LatencyRange latency_range)
{
if (!_registered (port_handle)) {
std::cerr << "WavesAudioBackend::set_latency_range (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;
return;
}
((WavesDataPort*)port_handle)->set_latency_range (latency_range, for_playback);
}
LatencyRange
WavesAudioBackend::get_latency_range (PortHandle port_handle, bool for_playback)
{
if (!_registered (port_handle)) {
std::cerr << "WavesAudioBackend::get_latency_range (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;
LatencyRange lr = {0,0};
return lr;
}
return ((WavesDataPort*)port_handle)->latency_range (for_playback);
}
/*
Copyright (C) 2013 Valeriy Kamyshniy
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.
*/
#include "waves_dataport.h"
#include "waves_audiobackend.h"
using namespace ARDOUR;
int
WavesAudioBackend::set_systemic_input_latency (uint32_t systemic_input_latency)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_systemic_input_latency (): " << systemic_input_latency << std::endl;
_systemic_input_latency = systemic_input_latency;
return 0;
}
int
WavesAudioBackend::set_systemic_output_latency (uint32_t systemic_output_latency)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_systemic_output_latency (): " << systemic_output_latency << std::endl;
_systemic_output_latency = systemic_output_latency;
return 0;
}
uint32_t
WavesAudioBackend::systemic_input_latency () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::systemic_input_latency ()" << std::endl;
return _systemic_input_latency;
}
uint32_t
WavesAudioBackend::systemic_output_latency () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::systemic_output_latency ()" << std::endl;
return _systemic_output_latency;
}
void
WavesAudioBackend::update_latencies ()
{
// COMMENTED DBG LOGS */ std::cout << "update_latencies:" << std::endl;
}
void
WavesAudioBackend::set_latency_range (PortHandle port_handle, bool for_playback, LatencyRange latency_range)
{
if (!_registered (port_handle)) {
std::cerr << "WavesAudioBackend::set_latency_range (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;
return;
}
((WavesDataPort*)port_handle)->set_latency_range (latency_range, for_playback);
}
LatencyRange
WavesAudioBackend::get_latency_range (PortHandle port_handle, bool for_playback)
{
if (!_registered (port_handle)) {
std::cerr << "WavesAudioBackend::get_latency_range (): Failed to find port [" << std::hex << port_handle << std::dec << "]!" << std::endl;
LatencyRange lr = {0,0};
return lr;
}
return ((WavesDataPort*)port_handle)->latency_range (for_playback);
}

View file

@ -1,354 +1,353 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include <boost/assign/list_of.hpp>
#include "waves_audiobackend.h"
#include "waves_midiport.h"
#include "waves_midi_event.h"
#include "waves_midi_buffer.h"
using namespace ARDOUR;
#ifdef __MACOS__
const std::vector<std::string> WavesAudioBackend::__available_midi_options = boost::assign::list_of ("None") ("CoreMIDI");
#elif _WINDOWS
const std::vector<std::string> WavesAudioBackend::__available_midi_options = boost::assign::list_of ("None") ("Multimedia Extensions");
#endif
std::vector<std::string>
WavesAudioBackend::enumerate_midi_options () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::enumerate_midi_options ()" << std::endl;
return __available_midi_options;
}
int
WavesAudioBackend::set_midi_option (const std::string& option)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_midi_option ( " << option << " )" << std::endl;
if (option == __available_midi_options[0]) {
_use_midi = false;
// COMMENTED DBG LOGS */ std::cout << "\tNO MIDI system used)" << std::endl;
}
else if (option == __available_midi_options[1]) {
_use_midi = true;
// COMMENTED DBG LOGS */ std::cout << "\tNO MIDI system used)" << std::endl;
}
else {
std::cerr << "WavesAudioBackend::set_midi_option (): Invalid MIDI option!" << std::endl;
return -1;
}
return 0;
}
std::string
WavesAudioBackend::midi_option () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::midi_option ():" << std::endl;
return * (__available_midi_options.begin () + (_use_midi?1:0));
}
int
WavesAudioBackend::midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buffer, void* port_buffer, uint32_t event_index)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_event_get ():" << std::endl;
if (buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_get () : NULL in the 'buffer' argument!\n";
return -1;
}
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_get () : NULL in the 'port_buffer' argument!\n";
return -1;
}
WavesMidiBuffer& source = * (WavesMidiBuffer*)port_buffer;
if (event_index >= source.size ()) {
std::cerr << "WavesAudioBackend::midi_event_get () : 'event_index' is out of the number of events stored in 'port_buffer'!\n";
return -1;
}
WavesMidiEvent* waves_midi_event = source[event_index];
timestamp = waves_midi_event->timestamp ();
size = waves_midi_event->size ();
*buffer = waves_midi_event->data ();
return 0;
}
int
WavesAudioBackend::midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_event_put ():" << std::endl;
if (buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_put () : NULL in the 'buffer' argument!\n";
return -1;
}
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_put () : NULL in the 'port_buffer' argument!\n";
return -1;
}
WavesMidiBuffer& target = * (WavesMidiBuffer*)port_buffer;
// COMMENTED FREQUENT DBG LOGS */ std::cout << "\t [" << target.name () << "]"<< std::endl;
if (target.size () && (pframes_t)target.back ()->timestamp () > timestamp) {
std::cerr << "WavesAudioBackend::midi_event_put (): The MIDI Event to put is a bit late!" << std::endl;
std::cerr << "\tprev timestamp is " << (pframes_t)target.back ()->timestamp () << " as the current one is " << timestamp << std::endl;
return -1;
}
target.push_back (new WavesMidiEvent (timestamp, buffer, size));
return 0;
}
uint32_t
WavesAudioBackend::get_midi_event_count (void* port_buffer)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::get_midi_event_count (): " << std::endl;
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::get_midi_event_count () : NULL in the 'port_buffer' argument!\n";
return -1;
}
// COMMENTED FREQUENT DBG LOGS */ std::cout << "\tcount = " << (* (WavesMidiBuffer*)port_buffer).size () << std::endl;
return (* (WavesMidiBuffer*)port_buffer).size ();
}
void
WavesAudioBackend::midi_clear (void* port_buffer)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_clear (): " << std::endl;
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_clear () : NULL in the 'port_buffer' argument!\n";
return;
}
(* (WavesMidiBuffer*)port_buffer).clear ();
}
void
WavesAudioBackend::_changed_midi_devices ()
{
if (_midi_device_manager.stream (false)) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.stream (false) failed!" << std::endl;
return;
}
_midi_device_manager.stop ();
if (_midi_device_manager.start () != 0) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.start () failed!" << std::endl;
return;
}
if (_register_system_midi_ports () != 0) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _register_system_midi_ports () failed!" << std::endl;
return;
}
manager.registration_callback ();
if (_midi_device_manager.stream (true)) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.stream (true) failed!" << std::endl;
return;
}
}
void
WavesAudioBackend::_unregister_system_midi_ports ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_unregister_system_midi_ports ()" << std::endl;
std::vector<WavesMidiPort*> physical_midi_ports = _physical_midi_inputs;
physical_midi_ports.insert (physical_midi_ports.begin (), _physical_midi_outputs.begin (), _physical_midi_outputs.end ());
for (std::vector<WavesMidiPort*>::const_iterator it = physical_midi_ports.begin (); it != physical_midi_ports.end (); ++it) {
std::vector<WavesDataPort*>::iterator port_iterator = std::find (_ports.begin (), _ports.end (), *it);
if (port_iterator == _ports.end ()) {
std::cerr << "WavesAudioBackend::_unregister_system_midi_ports (): Failed to find port [" << (*it)->name () << "]!" << std::endl;
}
else
_ports.erase (port_iterator);
delete *it;
}
_physical_midi_inputs.clear ();
_physical_midi_outputs.clear ();
}
int
WavesAudioBackend::_register_system_midi_ports ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_register_system_midi_ports ()" << std::endl;
LatencyRange lr = {0,0};
lr.min = lr.max = _buffer_size;
for (size_t i = 0; i<_ports.size ();) {
WavesMidiPort* midi_port = dynamic_cast<WavesMidiPort*> (_ports[i]);
if (!midi_port || !midi_port->is_physical () || !midi_port->is_terminal ()) {
++i;
continue;
}
if ((midi_port->is_input () && !midi_port->midi_device ()->is_output ()) ||
(midi_port->is_output () && !midi_port->midi_device ()->is_input ())) {
disconnect_all (midi_port);
unregister_port (midi_port);
continue; // to be here for further additions in the end of this loop
}
++i;
}
const std::vector<WavesMidiDevice *>& devices = _midi_device_manager.devices ();
for (std::vector<WavesMidiDevice*>::const_iterator it = devices.begin (); it != devices.end (); ++it) {
if ((*it)->is_input ()) {
std::string port_name = "system_midi:" + (*it)->name () + " capture";
WavesDataPort* port = _find_port (port_name);
WavesMidiPort* midi_port = dynamic_cast<WavesMidiPort*> (port);
if (midi_port && (midi_port->type () != DataType::MIDI ||
midi_port->midi_device () != *it ||
!midi_port->is_output () ||
!midi_port->is_physical () ||
!midi_port->is_terminal ())) {
std::cerr << "WavesAudioBackend::_register_system_midi_ports (): the port [" << midi_port->name () << "] is inconsystently constructed!" << std::endl;
disconnect_all (midi_port);
unregister_port (midi_port);
port = NULL;
}
if (port == NULL) {
port = _register_port ( port_name, DataType::MIDI , static_cast<ARDOUR::PortFlags> (IsOutput | IsPhysical | IsTerminal));
if (port == NULL) {
return -1;
}
((WavesMidiPort*)port)->set_midi_device (*it);
}
port->set_latency_range (lr, false);
}
if ((*it)->is_output ()) {
std::string port_name = "system_midi:" + (*it)->name () + " playback";
WavesDataPort* port = _find_port (port_name);
WavesMidiPort* midi_port = dynamic_cast<WavesMidiPort*> (port);
if (midi_port && (midi_port->type () != DataType::MIDI ||
midi_port->midi_device () != *it ||
!midi_port->is_input () ||
!midi_port->is_physical () ||
!midi_port->is_terminal ())) {
std::cerr << "WavesAudioBackend::_register_system_midi_ports (): the port [" << midi_port->name () << "] is inconsystently constructed!" << std::endl;
disconnect_all (midi_port);
unregister_port (midi_port);
}
if (port == NULL) {
port = _register_port (port_name,
DataType::MIDI,
static_cast<ARDOUR::PortFlags> (IsInput | IsPhysical | IsTerminal));
if (port == NULL) {
return -1;
}
}
((WavesMidiPort*)port)->set_midi_device ((*it));
port->set_latency_range (lr, true);
}
}
return 0;
}
int
WavesAudioBackend::_read_midi_data_from_devices ()
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::_read_midi_data_from_devices ():" << std::endl;
if (!_midi_device_manager.is_streaming ())
return 0;
_midi_device_manager.do_read ();
for (std::vector<WavesMidiPort*>::iterator it = _physical_midi_inputs.begin (); it != _physical_midi_inputs.end (); ++it) {
WavesMidiDevice* midi_device = (*it)->midi_device ();
WavesMidiBuffer& waves_midi_buffer = (*it)->buffer ();
waves_midi_buffer.clear ();
while (WavesMidiEvent *waves_midi_event = midi_device->dequeue_input_waves_midi_event ()) {
int32_t timestamp_st = _buffer_size - (_sample_time_at_cycle_start - waves_midi_event->timestamp ());
if (timestamp_st < 0) {
timestamp_st = 0;
}
else if (timestamp_st >= (int32_t)_buffer_size) {
timestamp_st = _buffer_size - 1;
}
waves_midi_event->set_timestamp (timestamp_st);
waves_midi_buffer.push_back (waves_midi_event);
}
}
return 0;
}
int
WavesAudioBackend::_write_midi_data_to_devices (pframes_t nframes)
{
if (!_midi_device_manager.is_streaming ())
return 0;
for (std::vector<WavesMidiPort*>::iterator it = _physical_midi_outputs.begin (); it != _physical_midi_outputs.end (); ++it) {
WavesMidiDevice* midi_device = (*it)->midi_device ();
WavesMidiBuffer &waves_midi_buffer = * (WavesMidiBuffer*) (*it)->get_buffer (nframes);
for (WavesMidiBufferIterator it = waves_midi_buffer.begin (); it != waves_midi_buffer.end ();) {
WavesMidiEvent* waves_midi_event = *it;
waves_midi_buffer.erase (it);
waves_midi_event->set_timestamp (_sample_time_at_cycle_start + waves_midi_event->timestamp () + nframes);
midi_device->enqueue_output_waves_midi_event (waves_midi_event);
}
}
_midi_device_manager.do_write ();
return 0;
}
/*
Copyright (C) 2013 Valeriy Kamyshniy
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.
*/
#include <boost/assign/list_of.hpp>
#include "waves_audiobackend.h"
#include "waves_midiport.h"
#include "waves_midi_event.h"
#include "waves_midi_buffer.h"
using namespace ARDOUR;
#ifdef __MACOS__
const std::vector<std::string> WavesAudioBackend::__available_midi_options = boost::assign::list_of ("None") ("CoreMIDI");
#elif _WINDOWS
const std::vector<std::string> WavesAudioBackend::__available_midi_options = boost::assign::list_of ("None") ("Multimedia Extensions");
#endif
std::vector<std::string>
WavesAudioBackend::enumerate_midi_options () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::enumerate_midi_options ()" << std::endl;
return __available_midi_options;
}
int
WavesAudioBackend::set_midi_option (const std::string& option)
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_midi_option ( " << option << " )" << std::endl;
if (option == __available_midi_options[0]) {
_use_midi = false;
// COMMENTED DBG LOGS */ std::cout << "\tNO MIDI system used)" << std::endl;
}
else if (option == __available_midi_options[1]) {
_use_midi = true;
// COMMENTED DBG LOGS */ std::cout << "\tNO MIDI system used)" << std::endl;
}
else {
std::cerr << "WavesAudioBackend::set_midi_option (): Invalid MIDI option!" << std::endl;
return -1;
}
return 0;
}
std::string
WavesAudioBackend::midi_option () const
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::midi_option ():" << std::endl;
return * (__available_midi_options.begin () + (_use_midi?1:0));
}
int
WavesAudioBackend::midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buffer, void* port_buffer, uint32_t event_index)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_event_get ():" << std::endl;
if (buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_get () : NULL in the 'buffer' argument!\n";
return -1;
}
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_get () : NULL in the 'port_buffer' argument!\n";
return -1;
}
WavesMidiBuffer& source = * (WavesMidiBuffer*)port_buffer;
if (event_index >= source.size ()) {
std::cerr << "WavesAudioBackend::midi_event_get () : 'event_index' is out of the number of events stored in 'port_buffer'!\n";
return -1;
}
WavesMidiEvent* waves_midi_event = source[event_index];
timestamp = waves_midi_event->timestamp ();
size = waves_midi_event->size ();
*buffer = waves_midi_event->data ();
return 0;
}
int
WavesAudioBackend::midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_event_put ():" << std::endl;
if (buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_put () : NULL in the 'buffer' argument!\n";
return -1;
}
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_event_put () : NULL in the 'port_buffer' argument!\n";
return -1;
}
WavesMidiBuffer& target = * (WavesMidiBuffer*)port_buffer;
// COMMENTED FREQUENT DBG LOGS */ std::cout << "\t [" << target.name () << "]"<< std::endl;
if (target.size () && (pframes_t)target.back ()->timestamp () > timestamp) {
std::cerr << "WavesAudioBackend::midi_event_put (): The MIDI Event to put is a bit late!" << std::endl;
std::cerr << "\tprev timestamp is " << (pframes_t)target.back ()->timestamp () << " as the current one is " << timestamp << std::endl;
return -1;
}
target.push_back (new WavesMidiEvent (timestamp, buffer, size));
return 0;
}
uint32_t
WavesAudioBackend::get_midi_event_count (void* port_buffer)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::get_midi_event_count (): " << std::endl;
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::get_midi_event_count () : NULL in the 'port_buffer' argument!\n";
return -1;
}
// COMMENTED FREQUENT DBG LOGS */ std::cout << "\tcount = " << (* (WavesMidiBuffer*)port_buffer).size () << std::endl;
return (* (WavesMidiBuffer*)port_buffer).size ();
}
void
WavesAudioBackend::midi_clear (void* port_buffer)
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::midi_clear (): " << std::endl;
if (port_buffer == NULL) {
std::cerr << "WavesAudioBackend::midi_clear () : NULL in the 'port_buffer' argument!\n";
return;
}
(* (WavesMidiBuffer*)port_buffer).clear ();
}
void
WavesAudioBackend::_changed_midi_devices ()
{
if (_midi_device_manager.stream (false)) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.stream (false) failed!" << std::endl;
return;
}
_midi_device_manager.stop ();
if (_midi_device_manager.start () != 0) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.start () failed!" << std::endl;
return;
}
if (_register_system_midi_ports () != 0) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _register_system_midi_ports () failed!" << std::endl;
return;
}
manager.registration_callback ();
if (_midi_device_manager.stream (true)) {
std::cerr << "WavesAudioBackend::_changed_midi_devices (): _midi_device_manager.stream (true) failed!" << std::endl;
return;
}
}
void
WavesAudioBackend::_unregister_system_midi_ports ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_unregister_system_midi_ports ()" << std::endl;
std::vector<WavesMidiPort*> physical_midi_ports = _physical_midi_inputs;
physical_midi_ports.insert (physical_midi_ports.begin (), _physical_midi_outputs.begin (), _physical_midi_outputs.end ());
for (std::vector<WavesMidiPort*>::const_iterator it = physical_midi_ports.begin (); it != physical_midi_ports.end (); ++it) {
std::vector<WavesDataPort*>::iterator port_iterator = std::find (_ports.begin (), _ports.end (), *it);
if (port_iterator == _ports.end ()) {
std::cerr << "WavesAudioBackend::_unregister_system_midi_ports (): Failed to find port [" << (*it)->name () << "]!" << std::endl;
}
else
_ports.erase (port_iterator);
delete *it;
}
_physical_midi_inputs.clear ();
_physical_midi_outputs.clear ();
}
int
WavesAudioBackend::_register_system_midi_ports ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_register_system_midi_ports ()" << std::endl;
LatencyRange lr = {0,0};
lr.min = lr.max = _buffer_size;
for (size_t i = 0; i<_ports.size ();) {
WavesMidiPort* midi_port = dynamic_cast<WavesMidiPort*> (_ports[i]);
if (!midi_port || !midi_port->is_physical () || !midi_port->is_terminal ()) {
++i;
continue;
}
if ((midi_port->is_input () && !midi_port->midi_device ()->is_output ()) ||
(midi_port->is_output () && !midi_port->midi_device ()->is_input ())) {
disconnect_all (midi_port);
unregister_port (midi_port);
continue; // to be here for further additions in the end of this loop
}
++i;
}
const std::vector<WavesMidiDevice *>& devices = _midi_device_manager.devices ();
for (std::vector<WavesMidiDevice*>::const_iterator it = devices.begin (); it != devices.end (); ++it) {
if ((*it)->is_input ()) {
std::string port_name = "system_midi:" + (*it)->name () + " capture";
WavesDataPort* port = _find_port (port_name);
WavesMidiPort* midi_port = dynamic_cast<WavesMidiPort*> (port);
if (midi_port && (midi_port->type () != DataType::MIDI ||
midi_port->midi_device () != *it ||
!midi_port->is_output () ||
!midi_port->is_physical () ||
!midi_port->is_terminal ())) {
std::cerr << "WavesAudioBackend::_register_system_midi_ports (): the port [" << midi_port->name () << "] is inconsystently constructed!" << std::endl;
disconnect_all (midi_port);
unregister_port (midi_port);
port = NULL;
}
if (port == NULL) {
port = _register_port ( port_name, DataType::MIDI , static_cast<ARDOUR::PortFlags> (IsOutput | IsPhysical | IsTerminal));
if (port == NULL) {
return -1;
}
((WavesMidiPort*)port)->set_midi_device (*it);
}
port->set_latency_range (lr, false);
}
if ((*it)->is_output ()) {
std::string port_name = "system_midi:" + (*it)->name () + " playback";
WavesDataPort* port = _find_port (port_name);
WavesMidiPort* midi_port = dynamic_cast<WavesMidiPort*> (port);
if (midi_port && (midi_port->type () != DataType::MIDI ||
midi_port->midi_device () != *it ||
!midi_port->is_input () ||
!midi_port->is_physical () ||
!midi_port->is_terminal ())) {
std::cerr << "WavesAudioBackend::_register_system_midi_ports (): the port [" << midi_port->name () << "] is inconsystently constructed!" << std::endl;
disconnect_all (midi_port);
unregister_port (midi_port);
}
if (port == NULL) {
port = _register_port (port_name,
DataType::MIDI,
static_cast<ARDOUR::PortFlags> (IsInput | IsPhysical | IsTerminal));
if (port == NULL) {
return -1;
}
}
((WavesMidiPort*)port)->set_midi_device ((*it));
port->set_latency_range (lr, true);
}
}
return 0;
}
int
WavesAudioBackend::_read_midi_data_from_devices ()
{
// COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::_read_midi_data_from_devices ():" << std::endl;
if (!_midi_device_manager.is_streaming ())
return 0;
_midi_device_manager.do_read ();
for (std::vector<WavesMidiPort*>::iterator it = _physical_midi_inputs.begin (); it != _physical_midi_inputs.end (); ++it) {
WavesMidiDevice* midi_device = (*it)->midi_device ();
WavesMidiBuffer& waves_midi_buffer = (*it)->buffer ();
waves_midi_buffer.clear ();
while (WavesMidiEvent *waves_midi_event = midi_device->dequeue_input_waves_midi_event ()) {
int32_t timestamp_st = _buffer_size - (_sample_time_at_cycle_start - waves_midi_event->timestamp ());
if (timestamp_st < 0) {
timestamp_st = 0;
}
else if (timestamp_st >= (int32_t)_buffer_size) {
timestamp_st = _buffer_size - 1;
}
waves_midi_event->set_timestamp (timestamp_st);
waves_midi_buffer.push_back (waves_midi_event);
}
}
return 0;
}
int
WavesAudioBackend::_write_midi_data_to_devices (pframes_t nframes)
{
if (!_midi_device_manager.is_streaming ())
return 0;
for (std::vector<WavesMidiPort*>::iterator it = _physical_midi_outputs.begin (); it != _physical_midi_outputs.end (); ++it) {
WavesMidiDevice* midi_device = (*it)->midi_device ();
WavesMidiBuffer &waves_midi_buffer = * (WavesMidiBuffer*) (*it)->get_buffer (nframes);
for (WavesMidiBufferIterator it = waves_midi_buffer.begin (); it != waves_midi_buffer.end ();) {
WavesMidiEvent* waves_midi_event = *it;
waves_midi_buffer.erase (it);
waves_midi_event->set_timestamp (_sample_time_at_cycle_start + waves_midi_event->timestamp () + nframes);
midi_device->enqueue_output_waves_midi_event (waves_midi_event);
}
}
_midi_device_manager.do_write ();
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,62 +1,62 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include "waves_audioport.h"
using namespace ARDOUR;
WavesAudioPort::WavesAudioPort (const std::string& port_name, PortFlags flags)
: WavesDataPort (port_name, flags)
{
memset (_buffer, 0, sizeof (_buffer));
}
void* WavesAudioPort::get_buffer (pframes_t nframes)
{
if (is_input ()) {
std::vector<WavesDataPort*>::const_iterator it = get_connections ().begin ();
if (it != get_connections ().end ()) {
/* In fact, the static casting to (const WavesAudioPort*) is not that safe.
* However, mixing the buffers is assumed in the time critical conditions.
* Base class WavesDataPort takes is supposed to provide enough consistentcy
* of the connections.
*/
for (memcpy (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes * sizeof (Sample)), ++it;
it != get_connections ().end ();
++it) {
Sample* tgt = buffer ();
const Sample* src = ((const WavesAudioPort*)*it)->const_buffer ();
for (uint32_t frame = 0; frame < nframes; ++frame, ++tgt, ++src) {
*tgt += *src;
}
}
}
}
return _buffer;
}
void
WavesAudioPort::_wipe_buffer()
{
memset (_buffer, 0, sizeof (_buffer));
}
/*
Copyright (C) 2013 Valeriy Kamyshniy
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.
*/
#include "waves_audioport.h"
using namespace ARDOUR;
WavesAudioPort::WavesAudioPort (const std::string& port_name, PortFlags flags)
: WavesDataPort (port_name, flags)
{
memset (_buffer, 0, sizeof (_buffer));
}
void* WavesAudioPort::get_buffer (pframes_t nframes)
{
if (is_input ()) {
std::vector<WavesDataPort*>::const_iterator it = get_connections ().begin ();
if (it != get_connections ().end ()) {
/* In fact, the static casting to (const WavesAudioPort*) is not that safe.
* However, mixing the buffers is assumed in the time critical conditions.
* Base class WavesDataPort takes is supposed to provide enough consistentcy
* of the connections.
*/
for (memcpy (_buffer, ((const WavesAudioPort*)*it)->const_buffer (), nframes * sizeof (Sample)), ++it;
it != get_connections ().end ();
++it) {
Sample* tgt = buffer ();
const Sample* src = ((const WavesAudioPort*)*it)->const_buffer ();
for (uint32_t frame = 0; frame < nframes; ++frame, ++tgt, ++src) {
*tgt += *src;
}
}
}
}
return _buffer;
}
void
WavesAudioPort::_wipe_buffer()
{
memset (_buffer, 0, sizeof (_buffer));
}

View file

@ -1,58 +1,58 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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 __libardour_waves_audioport_h__
#define __libardour_waves_audioport_h__
#include "memory.h"
#include "waves_dataport.h"
namespace ARDOUR {
class WavesAudioPort : public WavesDataPort {
public:
enum BufferSize {
MAX_BUFFER_SIZE_SAMPLES = 8192,
MAX_BUFFER_SIZE_BYTES = sizeof (Sample) * MAX_BUFFER_SIZE_SAMPLES
};
WavesAudioPort (const std::string& port_name, PortFlags flags);
virtual ~WavesAudioPort () { };
virtual DataType type () const { return DataType::AUDIO; };
inline Sample* buffer () { return _buffer; }
inline const Sample* const_buffer () const { return _buffer; }
virtual void* get_buffer (pframes_t nframes);
protected:
virtual void _wipe_buffer();
private:
Sample _buffer[MAX_BUFFER_SIZE_SAMPLES];
};
} // namespace
#endif /* __libardour_waves_audioport_h__ */
/*
Copyright (C) 2013 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.
*/
#ifndef __libardour_waves_audioport_h__
#define __libardour_waves_audioport_h__
#include "memory.h"
#include "waves_dataport.h"
namespace ARDOUR {
class WavesAudioPort : public WavesDataPort {
public:
enum BufferSize {
MAX_BUFFER_SIZE_SAMPLES = 8192,
MAX_BUFFER_SIZE_BYTES = sizeof (Sample) * MAX_BUFFER_SIZE_SAMPLES
};
WavesAudioPort (const std::string& port_name, PortFlags flags);
virtual ~WavesAudioPort () { };
virtual DataType type () const { return DataType::AUDIO; };
inline Sample* buffer () { return _buffer; }
inline const Sample* const_buffer () const { return _buffer; }
virtual void* get_buffer (pframes_t nframes);
protected:
virtual void _wipe_buffer();
private:
Sample _buffer[MAX_BUFFER_SIZE_SAMPLES];
};
} // namespace
#endif /* __libardour_waves_audioport_h__ */

View file

@ -1,142 +1,142 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include "waves_dataport.h"
using namespace ARDOUR;
WavesDataPort::WavesDataPort (const std::string& inport_name, PortFlags inflags)
: _name (inport_name)
, _flags (inflags)
{
_capture_latency_range.min =
_capture_latency_range.max =
_playback_latency_range.min =
_playback_latency_range.max = 0;
}
WavesDataPort::~WavesDataPort ()
{
disconnect_all ();
}
int WavesDataPort::connect (WavesDataPort *port)
{
if (!port) {
std::cerr << "WavesDataPort::connect (): invalid (null) port to connect to!" << std::endl;
return -1;
}
if (type () != port->type ()) {
std::cerr << "WavesDataPort::connect (): wrong type of the port to connect to!" << std::endl;
return -1;
}
if (is_output () && port->is_output ()) {
std::cerr << "WavesDataPort::connect (): attempt to connect output port to output port!" << std::endl;
return -1;
}
if (is_input () && port->is_input ()) {
std::cerr << "WavesDataPort::connect (): attempt to connect input port to input port!" << std::endl;
return -1;
}
if (this == port) {
std::cerr << "WavesDataPort::connect (): attempt to connect port to itself!" << std::endl;
return -1;
}
if (is_connected (port)) {
std::cerr << "WavesDataPort::connect (): the ports are already connected!" << std::endl;
return -1;
}
_connect (port, true);
return 0;
}
void WavesDataPort::_connect (WavesDataPort *port, bool api_call)
{
_connections.push_back (port);
if (api_call) {
port->_connect (this, false);
}
}
int WavesDataPort::disconnect (WavesDataPort *port)
{
if (port == NULL) {
std::cerr << "WavesDataPort::disconnect (): invalid (null) port to disconnect from!" << std::endl;
return -1;
}
if (!is_connected (port)) {
std::cerr << "WavesDataPort::disconnect (): the ports are not connected!" << std::endl;
return -1;
}
_disconnect (port, true);
return 0;
}
void WavesDataPort::_disconnect (WavesDataPort *port, bool api_call)
{
std::vector<WavesDataPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
if (it != _connections.end ()) { // actually, it's supposed to be always true.
_connections.erase (it);
}
if (api_call) {
port->_disconnect (this, false);
}
if (is_input() && _connections.empty())
{
_wipe_buffer();
}
}
void WavesDataPort::disconnect_all ()
{
while (!_connections.empty ()) {
_connections.back ()->_disconnect (this, false);
_connections.pop_back ();
}
}
bool WavesDataPort::is_physically_connected () const
{
for (std::vector<WavesDataPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
if ((*it)->is_physical ()) {
return true;
}
}
return false;
}
/*
Copyright (C) 2013 Valeriy Kamyshniy
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.
*/
#include "waves_dataport.h"
using namespace ARDOUR;
WavesDataPort::WavesDataPort (const std::string& inport_name, PortFlags inflags)
: _name (inport_name)
, _flags (inflags)
{
_capture_latency_range.min =
_capture_latency_range.max =
_playback_latency_range.min =
_playback_latency_range.max = 0;
}
WavesDataPort::~WavesDataPort ()
{
disconnect_all ();
}
int WavesDataPort::connect (WavesDataPort *port)
{
if (!port) {
std::cerr << "WavesDataPort::connect (): invalid (null) port to connect to!" << std::endl;
return -1;
}
if (type () != port->type ()) {
std::cerr << "WavesDataPort::connect (): wrong type of the port to connect to!" << std::endl;
return -1;
}
if (is_output () && port->is_output ()) {
std::cerr << "WavesDataPort::connect (): attempt to connect output port to output port!" << std::endl;
return -1;
}
if (is_input () && port->is_input ()) {
std::cerr << "WavesDataPort::connect (): attempt to connect input port to input port!" << std::endl;
return -1;
}
if (this == port) {
std::cerr << "WavesDataPort::connect (): attempt to connect port to itself!" << std::endl;
return -1;
}
if (is_connected (port)) {
std::cerr << "WavesDataPort::connect (): the ports are already connected!" << std::endl;
return -1;
}
_connect (port, true);
return 0;
}
void WavesDataPort::_connect (WavesDataPort *port, bool api_call)
{
_connections.push_back (port);
if (api_call) {
port->_connect (this, false);
}
}
int WavesDataPort::disconnect (WavesDataPort *port)
{
if (port == NULL) {
std::cerr << "WavesDataPort::disconnect (): invalid (null) port to disconnect from!" << std::endl;
return -1;
}
if (!is_connected (port)) {
std::cerr << "WavesDataPort::disconnect (): the ports are not connected!" << std::endl;
return -1;
}
_disconnect (port, true);
return 0;
}
void WavesDataPort::_disconnect (WavesDataPort *port, bool api_call)
{
std::vector<WavesDataPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
if (it != _connections.end ()) { // actually, it's supposed to be always true.
_connections.erase (it);
}
if (api_call) {
port->_disconnect (this, false);
}
if (is_input() && _connections.empty())
{
_wipe_buffer();
}
}
void WavesDataPort::disconnect_all ()
{
while (!_connections.empty ()) {
_connections.back ()->_disconnect (this, false);
_connections.pop_back ();
}
}
bool WavesDataPort::is_physically_connected () const
{
for (std::vector<WavesDataPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
if ((*it)->is_physical ()) {
return true;
}
}
return false;
}

View file

@ -1,115 +1,115 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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 __libardour_waves_dataport_h__
#define __libardour_waves_dataport_h__
#include "ardour/types.h"
#include "memory.h"
namespace ARDOUR {
class WavesDataPort {
public:
virtual ~WavesDataPort ();
inline const std::string& name () const
{
return _name;
}
int set_name (const std::string &name)
{
_name = name;
return 0;
}
virtual DataType type () const = 0;
inline PortFlags flags () const
{
return _flags;
}
inline bool is_input () { return flags () & IsInput; }
inline bool is_output () { return flags () & IsOutput; }
inline bool is_physical () { return flags () & IsPhysical; }
inline bool is_terminal () { return flags () & IsTerminal; }
inline operator void* () { return (void*)this; }
inline const LatencyRange& latency_range (bool for_playback) const
{
return for_playback ? _playback_latency_range : _capture_latency_range;
}
inline void set_latency_range (const LatencyRange &latency_range, bool for_playback)
{
if (for_playback)
{
_playback_latency_range = latency_range;
}
else
{
_capture_latency_range = latency_range;
}
}
int connect (WavesDataPort *port);
int disconnect (WavesDataPort *port);
void disconnect_all ();
bool inline is_connected (const WavesDataPort *port) const
{
return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
}
bool inline is_connected () const
{
return _connections.size () != 0;
}
bool is_physically_connected () const;
inline const std::vector<WavesDataPort *>& get_connections () const { return _connections; }
virtual void* get_buffer (pframes_t nframes) = 0;
protected:
WavesDataPort (const std::string& inport_name, PortFlags inflags);
virtual void _wipe_buffer() = 0;
private:
std::string _name;
const PortFlags _flags;
LatencyRange _capture_latency_range;
LatencyRange _playback_latency_range;
std::vector<WavesDataPort*> _connections;
void _connect (WavesDataPort* port, bool api_call);
void _disconnect (WavesDataPort* port, bool api_call);
};
} // namespace
#endif /* __libardour_waves_dataport_h__ */
/*
Copyright (C) 2013 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.
*/
#ifndef __libardour_waves_dataport_h__
#define __libardour_waves_dataport_h__
#include "ardour/types.h"
#include "memory.h"
namespace ARDOUR {
class WavesDataPort {
public:
virtual ~WavesDataPort ();
inline const std::string& name () const
{
return _name;
}
int set_name (const std::string &name)
{
_name = name;
return 0;
}
virtual DataType type () const = 0;
inline PortFlags flags () const
{
return _flags;
}
inline bool is_input () { return flags () & IsInput; }
inline bool is_output () { return flags () & IsOutput; }
inline bool is_physical () { return flags () & IsPhysical; }
inline bool is_terminal () { return flags () & IsTerminal; }
inline operator void* () { return (void*)this; }
inline const LatencyRange& latency_range (bool for_playback) const
{
return for_playback ? _playback_latency_range : _capture_latency_range;
}
inline void set_latency_range (const LatencyRange &latency_range, bool for_playback)
{
if (for_playback)
{
_playback_latency_range = latency_range;
}
else
{
_capture_latency_range = latency_range;
}
}
int connect (WavesDataPort *port);
int disconnect (WavesDataPort *port);
void disconnect_all ();
bool inline is_connected (const WavesDataPort *port) const
{
return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
}
bool inline is_connected () const
{
return _connections.size () != 0;
}
bool is_physically_connected () const;
inline const std::vector<WavesDataPort *>& get_connections () const { return _connections; }
virtual void* get_buffer (pframes_t nframes) = 0;
protected:
WavesDataPort (const std::string& inport_name, PortFlags inflags);
virtual void _wipe_buffer() = 0;
private:
std::string _name;
const PortFlags _flags;
LatencyRange _capture_latency_range;
LatencyRange _playback_latency_range;
std::vector<WavesDataPort*> _connections;
void _connect (WavesDataPort* port, bool api_call);
void _disconnect (WavesDataPort* port, bool api_call);
};
} // namespace
#endif /* __libardour_waves_dataport_h__ */

View file

@ -1,50 +1,49 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include "waves_midi_buffer.h"
#include "waves_midi_event.h"
using namespace ARDOUR;
WavesMidiBuffer::WavesMidiBuffer (std::string name)
: std::vector<WavesMidiEvent*> ()
, _name (name)
{
}
WavesMidiBuffer::~WavesMidiBuffer ()
{
clear ();
}
void WavesMidiBuffer::clear ()
{
for (WavesMidiBufferIterator it = begin (); it != end (); ++it)
delete *it;
std::vector<WavesMidiEvent*>::clear ();
}
WavesMidiBuffer& WavesMidiBuffer::operator += (const WavesMidiBuffer& source)
{
for (WavesMidiBufferConstIterator it = source.begin (); it != source.end (); ++it) {
push_back (new WavesMidiEvent (**it));
}
return *this;
}
/*
Copyright (C) 2013 Valeriy amyshniy
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.
*/
#include "waves_midi_buffer.h"
#include "waves_midi_event.h"
using namespace ARDOUR;
WavesMidiBuffer::WavesMidiBuffer (std::string name)
: std::vector<WavesMidiEvent*> ()
, _name (name)
{
}
WavesMidiBuffer::~WavesMidiBuffer ()
{
clear ();
}
void WavesMidiBuffer::clear ()
{
for (WavesMidiBufferIterator it = begin (); it != end (); ++it)
delete *it;
std::vector<WavesMidiEvent*>::clear ();
}
WavesMidiBuffer& WavesMidiBuffer::operator += (const WavesMidiBuffer& source)
{
for (WavesMidiBufferConstIterator it = source.begin (); it != source.end (); ++it) {
push_back (new WavesMidiEvent (**it));
}
return *this;
}

View file

@ -1,47 +1,48 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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 __libardour_waves_midi_buffer_h__
#define __libardour_waves_midi_buffer_h__
#include "ardour/types.h"
namespace ARDOUR {
class WavesMidiEvent;
class WavesMidiBuffer : public std::vector<WavesMidiEvent*>
{
public:
WavesMidiBuffer (std::string name);
~WavesMidiBuffer ();
void clear ();
WavesMidiBuffer& operator += (const WavesMidiBuffer& source);
inline const std::string name () { return _name; } // for DBG purpouses;
private:
const std::string _name;
};
typedef std::vector<WavesMidiEvent*>::iterator WavesMidiBufferIterator;
typedef std::vector<WavesMidiEvent*>::const_iterator WavesMidiBufferConstIterator;
} // namespace
#endif /* __libardour_waves_midi_buffer_h__ */
/*
Copyright (C) 2013 Valeriy amyshniy
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 __libardour_waves_midi_buffer_h__
#define __libardour_waves_midi_buffer_h__
#include "ardour/types.h"
namespace ARDOUR {
class WavesMidiEvent;
class WavesMidiBuffer : public std::vector<WavesMidiEvent*>
{
public:
WavesMidiBuffer (std::string name);
~WavesMidiBuffer ();
void clear ();
WavesMidiBuffer& operator += (const WavesMidiBuffer& source);
inline const std::string name () { return _name; } // for DBG purpouses;
private:
const std::string _name;
};
typedef std::vector<WavesMidiEvent*>::iterator WavesMidiBufferIterator;
typedef std::vector<WavesMidiEvent*>::const_iterator WavesMidiBufferConstIterator;
} // namespace
#endif /* __libardour_waves_midi_buffer_h__ */

View file

@ -1,268 +1,268 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include "waves_midi_device.h"
#include "waves_midi_event.h"
// use non-zero latency because we want output to be timestapmed
#define LATENCY 0
#define QUEUE_LENGTH 1024
using namespace ARDOUR;
WavesMidiDevice::WavesMidiDevice (const std::string& device_name)
: _pm_input_id (pmNoDevice)
, _pm_output_id (pmNoDevice)
, _name (device_name)
, _input_queue (NULL)
, _output_queue (NULL)
, _input_pm_stream (NULL)
, _output_pm_stream (NULL)
, _incomplete_waves_midi_event (NULL)
{
validate ();
}
WavesMidiDevice::~WavesMidiDevice ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::~WavesMidiDevice ():" << name () << std::endl;
close ();
}
void
WavesMidiDevice::validate ()
{
_pm_input_id =
_pm_output_id = pmNoDevice;
int count = Pm_CountDevices ();
for (int i = 0; i < count; i++) {
const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i);
if (pm_device_info == NULL) {
continue;
}
if (name () == pm_device_info->name) {
if (pm_device_info->input){
_pm_input_id = i;
}
if (pm_device_info->output){
_pm_output_id = i;
}
}
}
}
int
WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open ():" << name () << std::endl;
if (is_input () && !_input_pm_stream) {
if (pmNoError != Pm_OpenInput (&_input_pm_stream,
_pm_input_id,
NULL,
1024,
time_proc,
time_info)) {
std::cerr << "WavesMidiDevice::open (): Pm_OpenInput () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
_input_pm_stream = NULL;
_pm_input_id = pmNoDevice;
return -1;
}
_input_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*));
if (NULL == _input_queue) {
std::cerr << "WavesMidiDevice::open (): _input_queue = Pm_QueueCreate () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
close ();
return -1;
}
}
if (is_output () && !_output_pm_stream) {
if (pmNoError != Pm_OpenOutput (&_output_pm_stream,
_pm_output_id,
NULL,
1024,
time_proc,
time_info,
LATENCY)) {
std::cerr << "WavesMidiDevice::open (): Pm_OpenOutput () failed for " << _pm_output_id << "-[" << name () << "]!" << std::endl;
_output_pm_stream = NULL;
_pm_output_id = pmNoDevice;
return -1;
}
_output_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*));
if (NULL == _output_queue) {
std::cerr << "WavesMidiDevice::open (): _output_queue = Pm_QueueCreate () failed for " << _pm_output_id << "-[" << name () << "]!" << std::endl;
close ();
return -1;
}
}
return 0;
}
void
WavesMidiDevice::close ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::close ():" << name () << std::endl;
WavesMidiEvent *waves_midi_event;
if (_input_pm_stream) {
Pm_Close (_input_pm_stream);
while (1 == Pm_Dequeue (_input_queue, &waves_midi_event)) {
delete waves_midi_event;
}
Pm_QueueDestroy (_input_queue);
_input_queue = NULL;
_input_pm_stream = NULL;
_pm_input_id = pmNoDevice;
}
if ( _output_pm_stream ) {
Pm_Close (_output_pm_stream);
while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) {
delete waves_midi_event;
}
Pm_QueueDestroy (_output_queue);
_output_queue = NULL;
_output_pm_stream = NULL;
_pm_output_id = pmNoDevice;
}
}
void
WavesMidiDevice::do_io ()
{
read_midi ();
write_midi ();
}
void
WavesMidiDevice::read_midi ()
{
if (NULL == _input_pm_stream) {
return;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
while (Pm_Poll (_input_pm_stream) > 0) {
PmEvent pm_event; // just one message at a time
int result = Pm_Read (_input_pm_stream, &pm_event, 1);
if (result < 0) {
std::cerr << "WavesMidiDevice::_read_midi (): Pm_Read () failed (" << result << ") for [" << name () << "]!" << std::endl;
break;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] evt-tm:" << pm_event.timestamp << std::endl;
if (_incomplete_waves_midi_event == NULL ) {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : new _incomplete_waves_midi_event" << std::endl;
_incomplete_waves_midi_event = new WavesMidiEvent (pm_event.timestamp);
}
WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event);
if (nested_pm_event) {
Pm_Enqueue (_input_queue, &nested_pm_event);
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : Pm_Enqueue (_input_queue, nested_pm_event)" << std::endl;
}
switch ( _incomplete_waves_midi_event->state ()) {
case WavesMidiEvent::BROKEN:
delete _incomplete_waves_midi_event;
_incomplete_waves_midi_event = NULL;
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : case WavesMidiEvent::BROKEN:" << std::endl;
break;
case WavesMidiEvent::COMPLETE:
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : Pm_Enqueue (_input_queue, _incomplete_waves_midi_event); " << std::hex << (void*)_incomplete_waves_midi_event << std::dec << std::endl;
Pm_Enqueue (_input_queue, &_incomplete_waves_midi_event);
_incomplete_waves_midi_event = NULL;
break;
default:
break;
}
}
}
void
WavesMidiDevice::write_midi ()
{
if (NULL == _output_pm_stream) {
return;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
PmError err;
WavesMidiEvent *waves_midi_event;
while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) {
if (waves_midi_event->sysex ()) {
// LATENCY compensation
err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ());
if (0 > err) {
std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteSysEx () failed (" << err << ")!" << std::endl;
};
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SYSEX used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl;
}
else
{
err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ());
if (0 > err) {
std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << std::endl;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl;
}
delete waves_midi_event;
}
return;
}
int
WavesMidiDevice::enqueue_output_waves_midi_event (const WavesMidiEvent* waves_midi_event)
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::enqueue_output_waves_midi_event (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
if (waves_midi_event == NULL) {
std::cerr << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << std::endl;
return -1;
}
PmError err = Pm_Enqueue (_output_queue, &waves_midi_event);
if (0 > err) {
std::cerr << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << std::endl;
return -1;
};
return 0;
}
WavesMidiEvent*
WavesMidiDevice::dequeue_input_waves_midi_event ()
{
WavesMidiEvent* waves_midi_event;
if (Pm_Dequeue (_input_queue, &waves_midi_event) == 1) {
return waves_midi_event;
}
return NULL;
}
/*
Copyright (C) 2013 Gorobchenko Dmytro
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.
*/
#include "waves_midi_device.h"
#include "waves_midi_event.h"
// use non-zero latency because we want output to be timestapmed
#define LATENCY 0
#define QUEUE_LENGTH 1024
using namespace ARDOUR;
WavesMidiDevice::WavesMidiDevice (const std::string& device_name)
: _pm_input_id (pmNoDevice)
, _pm_output_id (pmNoDevice)
, _name (device_name)
, _input_queue (NULL)
, _output_queue (NULL)
, _input_pm_stream (NULL)
, _output_pm_stream (NULL)
, _incomplete_waves_midi_event (NULL)
{
validate ();
}
WavesMidiDevice::~WavesMidiDevice ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::~WavesMidiDevice ():" << name () << std::endl;
close ();
}
void
WavesMidiDevice::validate ()
{
_pm_input_id =
_pm_output_id = pmNoDevice;
int count = Pm_CountDevices ();
for (int i = 0; i < count; i++) {
const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i);
if (pm_device_info == NULL) {
continue;
}
if (name () == pm_device_info->name) {
if (pm_device_info->input){
_pm_input_id = i;
}
if (pm_device_info->output){
_pm_output_id = i;
}
}
}
}
int
WavesMidiDevice::open (PmTimeProcPtr time_proc, void* time_info)
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::open ():" << name () << std::endl;
if (is_input () && !_input_pm_stream) {
if (pmNoError != Pm_OpenInput (&_input_pm_stream,
_pm_input_id,
NULL,
1024,
time_proc,
time_info)) {
std::cerr << "WavesMidiDevice::open (): Pm_OpenInput () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
_input_pm_stream = NULL;
_pm_input_id = pmNoDevice;
return -1;
}
_input_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*));
if (NULL == _input_queue) {
std::cerr << "WavesMidiDevice::open (): _input_queue = Pm_QueueCreate () failed for " << _pm_input_id << "-[" << name () << "]!" << std::endl;
close ();
return -1;
}
}
if (is_output () && !_output_pm_stream) {
if (pmNoError != Pm_OpenOutput (&_output_pm_stream,
_pm_output_id,
NULL,
1024,
time_proc,
time_info,
LATENCY)) {
std::cerr << "WavesMidiDevice::open (): Pm_OpenOutput () failed for " << _pm_output_id << "-[" << name () << "]!" << std::endl;
_output_pm_stream = NULL;
_pm_output_id = pmNoDevice;
return -1;
}
_output_queue = Pm_QueueCreate (QUEUE_LENGTH, sizeof (const WavesMidiEvent*));
if (NULL == _output_queue) {
std::cerr << "WavesMidiDevice::open (): _output_queue = Pm_QueueCreate () failed for " << _pm_output_id << "-[" << name () << "]!" << std::endl;
close ();
return -1;
}
}
return 0;
}
void
WavesMidiDevice::close ()
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::close ():" << name () << std::endl;
WavesMidiEvent *waves_midi_event;
if (_input_pm_stream) {
Pm_Close (_input_pm_stream);
while (1 == Pm_Dequeue (_input_queue, &waves_midi_event)) {
delete waves_midi_event;
}
Pm_QueueDestroy (_input_queue);
_input_queue = NULL;
_input_pm_stream = NULL;
_pm_input_id = pmNoDevice;
}
if ( _output_pm_stream ) {
Pm_Close (_output_pm_stream);
while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) {
delete waves_midi_event;
}
Pm_QueueDestroy (_output_queue);
_output_queue = NULL;
_output_pm_stream = NULL;
_pm_output_id = pmNoDevice;
}
}
void
WavesMidiDevice::do_io ()
{
read_midi ();
write_midi ();
}
void
WavesMidiDevice::read_midi ()
{
if (NULL == _input_pm_stream) {
return;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
while (Pm_Poll (_input_pm_stream) > 0) {
PmEvent pm_event; // just one message at a time
int result = Pm_Read (_input_pm_stream, &pm_event, 1);
if (result < 0) {
std::cerr << "WavesMidiDevice::_read_midi (): Pm_Read () failed (" << result << ") for [" << name () << "]!" << std::endl;
break;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] evt-tm:" << pm_event.timestamp << std::endl;
if (_incomplete_waves_midi_event == NULL ) {
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : new _incomplete_waves_midi_event" << std::endl;
_incomplete_waves_midi_event = new WavesMidiEvent (pm_event.timestamp);
}
WavesMidiEvent *nested_pm_event = _incomplete_waves_midi_event->append_data (pm_event);
if (nested_pm_event) {
Pm_Enqueue (_input_queue, &nested_pm_event);
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : Pm_Enqueue (_input_queue, nested_pm_event)" << std::endl;
}
switch ( _incomplete_waves_midi_event->state ()) {
case WavesMidiEvent::BROKEN:
delete _incomplete_waves_midi_event;
_incomplete_waves_midi_event = NULL;
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : case WavesMidiEvent::BROKEN:" << std::endl;
break;
case WavesMidiEvent::COMPLETE:
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_read_midi (): " << _pm_device_id << "-[" << name () << "] : Pm_Enqueue (_input_queue, _incomplete_waves_midi_event); " << std::hex << (void*)_incomplete_waves_midi_event << std::dec << std::endl;
Pm_Enqueue (_input_queue, &_incomplete_waves_midi_event);
_incomplete_waves_midi_event = NULL;
break;
default:
break;
}
}
}
void
WavesMidiDevice::write_midi ()
{
if (NULL == _output_pm_stream) {
return;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
PmError err;
WavesMidiEvent *waves_midi_event;
while (1 == Pm_Dequeue (_output_queue, &waves_midi_event)) {
if (waves_midi_event->sysex ()) {
// LATENCY compensation
err = Pm_WriteSysEx (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, waves_midi_event->data ());
if (0 > err) {
std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteSysEx () failed (" << err << ")!" << std::endl;
};
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SYSEX used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl;
}
else
{
err = Pm_WriteShort (_output_pm_stream, waves_midi_event->timestamp () - LATENCY, * (PmMessage*)waves_midi_event->data ());
if (0 > err) {
std::cout << "WavesMidiDevice::write_event_to_device (): [" << name () << "] Pm_WriteShort () failed (" << err << ")!" << std::endl;
}
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::_write_midi (): SHORTMSG used, ev->tm:" << waves_midi_event->timestamp () - LATENCY << std::endl;
}
delete waves_midi_event;
}
return;
}
int
WavesMidiDevice::enqueue_output_waves_midi_event (const WavesMidiEvent* waves_midi_event)
{
// COMMENTED DBG LOGS */ std::cout << "WavesMidiDevice::enqueue_output_waves_midi_event (): " << _pm_device_id << "-[" << name () << "]" << std::endl;
if (waves_midi_event == NULL) {
std::cerr << "WavesMidiDevice::put_event_to_callback (): 'waves_midi_event' is NULL!" << std::endl;
return -1;
}
PmError err = Pm_Enqueue (_output_queue, &waves_midi_event);
if (0 > err) {
std::cerr << "WavesMidiDevice::put_event_to_callback (): Pm_Enqueue () failed (" << err << ")!" << std::endl;
return -1;
};
return 0;
}
WavesMidiEvent*
WavesMidiDevice::dequeue_input_waves_midi_event ()
{
WavesMidiEvent* waves_midi_event;
if (Pm_Dequeue (_input_queue, &waves_midi_event) == 1) {
return waves_midi_event;
}
return NULL;
}

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
Copyright (C) 2013 Gorobchenko Dmytro
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

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
Copyright (C) 2013 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

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
Copyright (C) 2013 Gorobchenko Dmytro
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

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
Copyright (C) 2013 Valeriy amyshniy
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
@ -16,7 +16,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "memory.h"
#include "waves_midi_event.h"

View file

@ -1,75 +1,75 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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 __libardour_waves_midi_event_h__
#define __libardour_waves_midi_event_h__
#include <stdlib.h>
#include <portmidi/portmidi.h>
#include "ardour/types.h"
namespace ARDOUR {
class WavesMidiEvent
{
public:
enum State {
INCOMPLETE,
BROKEN,
COMPLETE
};
WavesMidiEvent (PmTimestamp timestamp);
WavesMidiEvent (PmTimestamp timestamp, const uint8_t* data, size_t datalen);
WavesMidiEvent (const WavesMidiEvent& source);
~WavesMidiEvent ();
WavesMidiEvent *append_data (const PmEvent &midi_event);
inline State state () const { return _state; };
inline size_t size () const { return _size; };
inline PmTimestamp timestamp () const { return _timestamp; };
inline void set_timestamp (PmTimestamp time_stamp) { _timestamp = time_stamp; };
inline const unsigned char* const_data () const { return _data; };
inline unsigned char* data () { return _data; };
inline bool operator< (const WavesMidiEvent &other) const { return timestamp () < other.timestamp (); };
inline bool sysex () const { return _data && (*_data == SYSEX); };
private:
enum
{
SYSEX = 0xF0,
EOX = 0xF7,
REAL_TIME_FIRST = 0xF8,
STATUS_FIRST = 0x80
};
size_t _size;
PmTimestamp _timestamp;
uint8_t *_data;
State _state;
static size_t _midi_message_size (PmMessage midi_message);
};
} // namespace
#endif /* __libardour_waves_midi_event_h__ */
/*
Copyright (C) 2013 Valeriy amyshniy
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 __libardour_waves_midi_event_h__
#define __libardour_waves_midi_event_h__
#include <stdlib.h>
#include <portmidi/portmidi.h>
#include "ardour/types.h"
namespace ARDOUR {
class WavesMidiEvent
{
public:
enum State {
INCOMPLETE,
BROKEN,
COMPLETE
};
WavesMidiEvent (PmTimestamp timestamp);
WavesMidiEvent (PmTimestamp timestamp, const uint8_t* data, size_t datalen);
WavesMidiEvent (const WavesMidiEvent& source);
~WavesMidiEvent ();
WavesMidiEvent *append_data (const PmEvent &midi_event);
inline State state () const { return _state; };
inline size_t size () const { return _size; };
inline PmTimestamp timestamp () const { return _timestamp; };
inline void set_timestamp (PmTimestamp time_stamp) { _timestamp = time_stamp; };
inline const unsigned char* const_data () const { return _data; };
inline unsigned char* data () { return _data; };
inline bool operator< (const WavesMidiEvent &other) const { return timestamp () < other.timestamp (); };
inline bool sysex () const { return _data && (*_data == SYSEX); };
private:
enum
{
SYSEX = 0xF0,
EOX = 0xF7,
REAL_TIME_FIRST = 0xF8,
STATUS_FIRST = 0x80
};
size_t _size;
PmTimestamp _timestamp;
uint8_t *_data;
State _state;
static size_t _midi_message_size (PmMessage midi_message);
};
} // namespace
#endif /* __libardour_waves_midi_event_h__ */

View file

@ -1,61 +1,61 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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.
*/
#include "waves_midiport.h"
#include "waves_midi_event.h"
using namespace ARDOUR;
WavesMidiPort::WavesMidiPort (const std::string& port_name, PortFlags flags)
: WavesDataPort (port_name, flags)
, _midi_device (NULL)
, _waves_midi_buffer (port_name)
{
}
void*
WavesMidiPort::get_buffer (pframes_t nframes)
{
if (is_input ()) {
std::vector<WavesDataPort*>::const_iterator cit = get_connections ().begin ();
if (cit != get_connections ().end ()) {
_waves_midi_buffer.clear ();
WavesMidiBuffer& target = _waves_midi_buffer;
do {
/* In fact, the static casting to (const WavesMidiPort*) is not that safe.
* However, mixing the buffers is assumed in the time critical conditions.
* Base class WavesDataPort is supposed to provide enough consistentcy
* of the connections.
*/
target += ((const WavesMidiPort*)*cit)->const_buffer ();
}while((++cit) != get_connections ().end ());
std::sort (target.begin (), target.end ());
}
}
return &_waves_midi_buffer;
}
void
WavesMidiPort::_wipe_buffer()
{
_waves_midi_buffer.clear ();
}
/*
Copyright (C) 2013 Gorobchenko Dmytro
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.
*/
#include "waves_midiport.h"
#include "waves_midi_event.h"
using namespace ARDOUR;
WavesMidiPort::WavesMidiPort (const std::string& port_name, PortFlags flags)
: WavesDataPort (port_name, flags)
, _midi_device (NULL)
, _waves_midi_buffer (port_name)
{
}
void*
WavesMidiPort::get_buffer (pframes_t nframes)
{
if (is_input ()) {
std::vector<WavesDataPort*>::const_iterator cit = get_connections ().begin ();
if (cit != get_connections ().end ()) {
_waves_midi_buffer.clear ();
WavesMidiBuffer& target = _waves_midi_buffer;
do {
/* In fact, the static casting to (const WavesMidiPort*) is not that safe.
* However, mixing the buffers is assumed in the time critical conditions.
* Base class WavesDataPort is supposed to provide enough consistentcy
* of the connections.
*/
target += ((const WavesMidiPort*)*cit)->const_buffer ();
}while((++cit) != get_connections ().end ());
std::sort (target.begin (), target.end ());
}
}
return &_waves_midi_buffer;
}
void
WavesMidiPort::_wipe_buffer()
{
_waves_midi_buffer.clear ();
}

View file

@ -1,64 +1,64 @@
/*
Copyright (C) 2014 Waves Audio Ltd.
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 __libardour_waves_midiport_h__
#define __libardour_waves_midiport_h__
#include "waves_dataport.h"
#include "waves_midi_buffer.h"
namespace ARDOUR {
class WavesMidiEvent;
class WavesMidiDevice;
class WavesMidiEvent;
class WavesMidiPort : public WavesDataPort {
public:
enum BufferSize {
// This value has nothing to do with reality as buffer of MIDI Port is not a flat array.
// It's an iterated list.
MAX_BUFFER_SIZE_BYTES = 8192
};
WavesMidiPort (const std::string& port_name, PortFlags flags);
virtual ~WavesMidiPort (){};
virtual DataType type () const { return DataType::MIDI; };
virtual void* get_buffer (pframes_t nframes);
inline WavesMidiBuffer& buffer () { return _waves_midi_buffer; }
inline const WavesMidiBuffer& const_buffer () const { return _waves_midi_buffer; }
inline void set_midi_device (WavesMidiDevice* midi_device) { _midi_device = midi_device; };
inline WavesMidiDevice* midi_device () const { return _midi_device; };
protected:
virtual void _wipe_buffer();
private:
WavesMidiDevice * _midi_device;
WavesMidiBuffer _waves_midi_buffer;
};
} // namespace
#endif /* __libardour_waves_midiport_h__ */
/*
Copyright (C) 2013 Gorobchenko Dmytro
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 __libardour_waves_midiport_h__
#define __libardour_waves_midiport_h__
#include "waves_dataport.h"
#include "waves_midi_buffer.h"
namespace ARDOUR {
class WavesMidiEvent;
class WavesMidiDevice;
class WavesMidiEvent;
class WavesMidiPort : public WavesDataPort {
public:
enum BufferSize {
// This value has nothing to do with reality as buffer of MIDI Port is not a flat array.
// It's an iterated list.
MAX_BUFFER_SIZE_BYTES = 8192
};
WavesMidiPort (const std::string& port_name, PortFlags flags);
virtual ~WavesMidiPort (){};
virtual DataType type () const { return DataType::MIDI; };
virtual void* get_buffer (pframes_t nframes);
inline WavesMidiBuffer& buffer () { return _waves_midi_buffer; }
inline const WavesMidiBuffer& const_buffer () const { return _waves_midi_buffer; }
inline void set_midi_device (WavesMidiDevice* midi_device) { _midi_device = midi_device; };
inline WavesMidiDevice* midi_device () const { return _midi_device; };
protected:
virtual void _wipe_buffer();
private:
WavesMidiDevice * _midi_device;
WavesMidiBuffer _waves_midi_buffer;
};
} // namespace
#endif /* __libardour_waves_midiport_h__ */

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WCFourCC_h__
#define __WCFourCC_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
#if !defined(__WTByteOrder_h__)
#define __WTByteOrder_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WUComPtr_h__
#define __WUComPtr_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WUDefines_h__
#define __WUDefines_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WUMathConsts_h__
#define __WUMathConsts_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WUTypes_h__
#define __WUTypes_h__

View file

@ -1,49 +1,31 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
#ifndef __IncludeWindows_h__
#define __IncludeWindows_h__
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.
#ifdef _WINDOWS
/* Copy to include
#include "IncludeWindows.h"
*/
#ifndef __IncludeWindows_h__
#define __IncludeWindows_h__
#ifdef _WINDOWS
/* Copy to include
#include "IncludeWindows.h"
*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601 // Windows 7
#endif
#ifndef WINVER
#define WINVER 0x0601 // Windows 7
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX // DO NOT REMOVE NOMINMAX - DOING SO CAUSES CONFLICTS WITH STD INCLUDES (<limits> ...)
#endif
#include <WinSock2.h>
#include <Windows.h>
#include <objbase.h>
#endif // #if _WINDOWS
#endif // #ifndef __IncludeWindows_h__
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601 // Windows 7
#endif
#ifndef WINVER
#define WINVER 0x0601 // Windows 7
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX // DO NOT REMOVE NOMINMAX - DOING SO CAUSES CONFLICTS WITH STD INCLUDES (<limits> ...)
#endif
#include <WinSock2.h>
#include <Windows.h>
#include <objbase.h>
#endif // #if _WINDOWS
#endif // #ifndef __IncludeWindows_h__

View file

@ -1,23 +1,6 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRAudioDeviceManager.cpp
//!
@ -27,10 +10,6 @@
#include "WCMRAudioDeviceManager.h"
//**********************************************************************************************
// WCMRAudioDevice::WCMRAudioDevice
//
@ -39,27 +18,21 @@
//! and streaming will also be provided by the derived implementations.
//!
//! \param *pManager : The audio device manager that's managing this device.
//!
//! \return Nothing.
//!
//**********************************************************************************************
WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager)
WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager) :
m_pMyManager (pManager)
, m_ConnectionStatus (DeviceDisconnected)
, m_IsActive (false)
, m_IsStreaming (false)
, m_CurrentSamplingRate (-1)
, m_CurrentBufferSize (0)
, m_LeftMonitorChannel (-1)
, m_RightMonitorChannel (-1)
, m_MonitorGain (1.0f)
{
m_pMyManager = pManager;
m_DeviceName = "Unknown";
m_ConnectionStatus = DeviceDisconnected;
m_IsActive = false;
m_IsStreaming = false;
m_CurrentSamplingRate = -1;
m_CurrentBufferSize = 0;
m_LeftMonitorChannel = -1;
m_RightMonitorChannel = -1;
m_MonitorGain = 1.0f;
}
@ -565,6 +538,7 @@ uint32_t WCMRAudioDevice::GetLatency (bool isInput)
return 0;
}
//**********************************************************************************************
// WCMRAudioDeviceManager::WCMRAudioDeviceManager
//
@ -576,15 +550,13 @@ uint32_t WCMRAudioDevice::GetLatency (bool isInput)
//!
//**********************************************************************************************
WCMRAudioDeviceManager::WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter)
: m_pTheClient (pTheClient)
, m_eAudioDeviceFilter(eCurAudioDeviceFilter)
: m_eAudioDeviceFilter(eCurAudioDeviceFilter)
, m_CurrentDevice(0)
, m_pTheClient (pTheClient)
{
//The derived classes will do lot more init!
return;
}
//**********************************************************************************************
// WCMRAudioDeviceManager::~WCMRAudioDeviceManager
//
@ -599,19 +571,21 @@ WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
{
AUTO_FUNC_DEBUG;
std::cout << "API::Destroying AudioDeviceManager " << std::endl;
try
{
//Need to call release on our devices, and erase them from list
std::vector<WCMRAudioDevice*>::iterator deviceIter;
while (m_Devices.size())
{
WCMRAudioDevice *pDeviceToRelease = m_Devices.back();
m_Devices.pop_back();
if (pDeviceToRelease)
SAFE_RELEASE (pDeviceToRelease);
}
//The derived classes may want to do additional de-int!
// clean up device info list
{
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
while( m_DeviceInfoVec.size() )
{
DeviceInfo* devInfo = m_DeviceInfoVec.back();
m_DeviceInfoVec.pop_back();
delete devInfo;
}
}
delete m_CurrentDevice;
}
catch (...)
{
@ -621,109 +595,48 @@ WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
}
//**********************************************************************************************
// WCMRAudioDeviceManager::DoIdle_Private
//
//! Used for idle time processing. This calls each device's DoIdle so that it can perform it's own idle processing.
//!
//! \param none
//!
//! \return noErr if no devices have returned an error. An error code if any of the devices returned error.
//!
//**********************************************************************************************
WTErr WCMRAudioDeviceManager::DoIdle_Private()
WCMRAudioDevice* WCMRAudioDeviceManager::InitNewCurrentDevice(const std::string & deviceName)
{
WTErr retVal = eNoErr;
//Need to call DoIdle of all our devices...
std::vector<WCMRAudioDevice*>::iterator deviceIter;
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
return initNewCurrentDeviceImpl(deviceName);
}
void WCMRAudioDeviceManager::DestroyCurrentDevice()
{
return destroyCurrentDeviceImpl();
}
const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const
{
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
return m_DeviceInfoVec;
}
WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const
{
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin();
for (; iter != m_DeviceInfoVec.end(); ++iter)
{
WTErr thisDeviceErr = (*deviceIter)->DoIdle();
if (thisDeviceErr != eNoErr)
retVal = thisDeviceErr;
if (nameToMatch == (*iter)->m_DeviceName)
{
devInfo = *(*iter);
return eNoErr;
}
}
return (retVal);
return eRMResNotFound;
}
//**********************************************************************************************
// WCMRAudioDeviceManager::Devices_Private
//
//! Retrieve list of devices managed by this manager.
//!
//! \param none
//!
//! \return A vector containing the list of devices.
//!
//**********************************************************************************************
const WCMRAudioDeviceList& WCMRAudioDeviceManager::Devices_Private() const
WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
{
return (m_Devices);
return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);
}
//**********************************************************************************************
// *WCMRAudioDeviceManager::GetDeviceByName_Private
//
//! Locates a device based on device name.
//!
//! \param nameToMatch : Device to look for.
//!
//! \return Pointer to the device object if found, NULL otherwise.
//!
//**********************************************************************************************
WCMRAudioDevice *WCMRAudioDeviceManager::GetDeviceByName_Private(const std::string& nameToMatch) const
{
//Need to check all our devices...
WCMRAudioDevice *pRetVal = NULL;
WCMRAudioDeviceListConstIter deviceIter;
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
{
if ((*deviceIter)->DeviceName() == nameToMatch)
{
pRetVal = *deviceIter;
break;
}
}
return (pRetVal);
}
//**********************************************************************************************
// *WCMRAudioDeviceManager::GetDefaultDevice
//
//! Locates a device based on device name.
//!
//! \param nameToMatch : Device to look for.
//!
//! \return Pointer to the device object if found, NULL otherwise.
//!
//**********************************************************************************************
WCMRAudioDevice *WCMRAudioDeviceManager::GetDefaultDevice_Private()
{
//Need to check all our devices...
WCMRAudioDevice *pRetVal = NULL;
WCMRAudioDeviceListIter deviceIter = m_Devices.begin();
if(deviceIter != m_Devices.end())
{
pRetVal = *deviceIter;
}
return (pRetVal);
}
//**********************************************************************************************
// WCMRAudioDeviceManager::NotifyClient
//

View file

@ -1,23 +1,6 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRAudioDeviceManager.h
//!
@ -42,19 +25,35 @@
#include "WCRefManager.h"
#include "BasicTypes/WUTypes.h"
#include "WUErrors.h"
#include "WCThreadSafe.h"
#define WCUNUSEDPARAM(a)
//forward decl.
class WCMRAudioConnection;
class WCMRAudioDevice;
class WCMRAudioDeviceManager;
typedef std::vector<WCMRAudioDevice *> WCMRAudioDeviceList; ///< Vector for audio devices
typedef std::vector<WCMRAudioDevice *>::iterator WCMRAudioDeviceListIter; ///< Vector iterator for audio devices
typedef std::vector<WCMRAudioDevice *>::const_iterator WCMRAudioDeviceListConstIter; ///< Vector iterator for audio devices
typedef std::vector<WCMRAudioConnection *> WCMRAudioConnectionsList; ///< Vector for audio devices
typedef unsigned int DeviceID;
struct DeviceInfo
{
DeviceID m_DeviceId;
std::string m_DeviceName;
std::vector<int> m_AvailableSampleRates;
unsigned int m_MaxInputChannels;
unsigned int m_MaxOutputChannels;
DeviceInfo():
m_DeviceId(-1), m_DeviceName("Unknown"), m_MaxInputChannels(0), m_MaxOutputChannels(0)
{};
DeviceInfo(unsigned int deviceID, const std::string & deviceName):
m_DeviceId(deviceID), m_DeviceName(deviceName), m_MaxInputChannels(0), m_MaxOutputChannels(0)
{};
};
typedef std::vector<DeviceInfo*> DeviceInfoVec;
typedef DeviceInfoVec::iterator DeviceInfoVecIter;
typedef DeviceInfoVec::const_iterator DeviceInfoVecConstIter;
/// for notification... A client must derive it's class from us.
class WCMRAudioDeviceManagerClient
@ -71,6 +70,7 @@ class WCMRAudioDeviceManagerClient
BufferSizeChanged,
ClockSourceChanged,
DeviceStoppedStreaming,
DeviceStartsStreaming,
DeviceDroppedSamples,
DeviceConnectionLost,
DeviceGenericError,
@ -123,7 +123,7 @@ public:
{
DeviceAvailable,
DeviceDisconnected,
DeviceError
DeviceErrors
};
WCMRAudioDevice (WCMRAudioDeviceManager *pManager);///<Constructor
@ -167,6 +167,8 @@ public:
virtual WTErr SendCustomCommand (int customCommand, void *pCommandParam); ///< Send a custom command to the audiodevice...
virtual uint32_t GetLatency (bool isInput); ///Get latency.
virtual WTErr UpdateDeviceInfo () = 0;
protected:
WCMRAudioDeviceManager *m_pMyManager; ///< The manager who's managing this device, can be used for sending notifications!
@ -191,6 +193,7 @@ protected:
float m_MonitorGain; ///< Amount of gain to apply for monitoring signal.
};
// This enum is for choosing filter for audio devices scan
typedef enum eAudioDeviceFilter
{
@ -202,65 +205,44 @@ typedef enum eAudioDeviceFilter
eAudioDeviceFilterNum // Number of enums
} eAudioDeviceFilter;
//! WCMRAudioDeviceManager
/*! The Audio Device Manager class */
class WCMRAudioDeviceManager : public WCRefManager
{
private://< Private version of class functions which will be called by class's public function after mutex lock acquistion.
WCMRAudioDevice* GetDefaultDevice_Private();
WTErr DoIdle_Private();
const WCMRAudioDeviceList& Devices_Private() const;
WCMRAudioDevice* GetDeviceByName_Private(const std::string & nameToMatch) const;
public://< Public functions for the class.
WCMRAudioDevice* GetDefaultDevice()
{
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
return GetDefaultDevice_Private();
}
WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter); ///< constructor
virtual ~WCMRAudioDeviceManager(void); ///< Destructor
virtual WTErr DoIdle()
{
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
return DoIdle_Private();
}
//interfaces
WCMRAudioDevice* InitNewCurrentDevice(const std::string & deviceName);
void DestroyCurrentDevice();
const DeviceInfoVec DeviceInfoList () const;
WTErr GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const;
WTErr GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const;
const WCMRAudioDeviceList& Devices() const
{
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
return Devices_Private();
}
//virtual void EnableVerboseLogging(bool /*bEnable*/, const std::string& /*logFilePath*/) { };
WCMRAudioDevice* GetDeviceByName(const std::string & nameToMatch) const
{
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
return GetDeviceByName_Private(nameToMatch);
}
public:
WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter
); ///< constructor
virtual ~WCMRAudioDeviceManager(void); ///< Destructor
virtual WTErr UpdateDeviceList () = 0; //has to be overridden!
//This is primarily for use by WCMRAudioDevice and it's descendants... We could have made it
//protected and made WCMRAudioDevice a friend, and then in some way found a way to extend
//the friendship to WCMRAudioDevice's descendants, but that would require a lot of extra
//effort!
void NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam = NULL);
virtual void EnableVerboseLogging(bool /*bEnable*/, const std::string& /*logFilePath*/) { };
//notify backend
void NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam = NULL);
protected:
//< NOTE : Mutex protection is commented, but wrapper classes are still there, in case they are required in future.
//wvNS::wvThread::ThreadMutex m_AudioDeviceManagerMutex; ///< Mutex for Audio device manager class function access.
WCMRAudioDeviceManagerClient *m_pTheClient; ///< The device manager's client, used to send notifications.
mutable wvNS::wvThread::ThreadMutex m_AudioDeviceInfoVecMutex; // mutex to lock device info list
DeviceInfoVec m_DeviceInfoVec;
WCMRAudioDeviceList m_Devices; ///< List of all relevant devices devices
eAudioDeviceFilter m_eAudioDeviceFilter; // filter of 'm_Devices'
eAudioDeviceFilter m_eAudioDeviceFilter;
WCMRAudioDevice* m_CurrentDevice;
private:
// override in derived classes
// made private to avoid pure virtual function call
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName) = 0;
virtual void destroyCurrentDeviceImpl() = 0;
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const = 0;
virtual WTErr generateDeviceListImpl() = 0;
virtual WTErr updateDeviceListImpl() = 0;
WCMRAudioDeviceManagerClient *m_pTheClient; ///< The device manager's client, used to send notifications.
};
#endif //#ifndef __WCMRAudioDeviceManager_h_

View file

@ -1,23 +1,6 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRCoreAudioDeviceManager.cpp
//!
@ -58,6 +41,8 @@ static const int DEFAULT_SR = 44100;
///< The default buffer size.
static const int DEFAULT_BUFFERSIZE = 128;
static const int NONE_DEVICE_ID = -1;
///< Number of stalls to wait before notifying user...
static const int NUM_STALLS_FOR_NOTIFICATION = 2 * 50; // 2*50 corresponds to 2 * 50 x 42 ms idle timer - about 4 seconds.
static const int CHANGE_CHECK_COUNTER_PERIOD = 100; // 120 corresponds to 120 x 42 ms idle timer - about 4 seconds.
@ -166,7 +151,7 @@ WCMRCoreAudioDevice::WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager,
m_CurrentBufferSize = (int)bufferSize;
UpdateDeviceInfo(true /*updateSRSupported*/, true /* updateBufferSizes */);
UpdateDeviceInfo();
//should use a valid current SR...
if (m_SamplingRates.size())
@ -252,14 +237,11 @@ WCMRCoreAudioDevice::~WCMRCoreAudioDevice ()
// WCMRCoreAudioDevice::UpdateDeviceInfo
//
//! Updates Device Information about channels, sampling rates, buffer sizes.
//!
//! \param updateSRSupported : Is Sampling Rate support needs to be updated.
//! \param updateBufferSizes : Is buffer size support needs to be updated.
//!
//! \return WTErr.
//!
//**********************************************************************************************
WTErr WCMRCoreAudioDevice::UpdateDeviceInfo (bool updateSRSupported, bool updateBufferSizes)
WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
{
AUTO_FUNC_DEBUG;
@ -272,17 +254,8 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo (bool updateSRSupported, bool update
WTErr errSR = eNoErr;
WTErr errBS = eNoErr;
if (updateSRSupported)
{
errSR = UpdateDeviceSampleRates();
}
//update SR list... This is done conditionally, because some devices may not like
//changing the SR later on, just to check on things.
if (updateBufferSizes)
{
errBS = UpdateDeviceBufferSizes();
}
errSR = UpdateDeviceSampleRates();
errBS = UpdateDeviceBufferSizes();
if(errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr)
{
@ -786,7 +759,7 @@ WTErr WCMRCoreAudioDevice::SetCurrentSamplingRate (int newRate)
retVal = SetAndCheckCurrentSamplingRate (newRate);
if(retVal == eNoErr)
{
retVal = UpdateDeviceInfo (false/*updateSRSupported*/, true/*updateBufferSizes*/);
retVal = UpdateDeviceInfo ();
}
//reactivate it.
@ -1759,7 +1732,7 @@ WTErr WCMRCoreAudioDevice::SetActive (bool newState)
m_DropsReported = 0;
m_IgnoreThisDrop = true;
UpdateDeviceInfo(true /*updateSRSupported */, true /* updateBufferSizes#*/);
UpdateDeviceInfo();
}
@ -2317,14 +2290,10 @@ OSStatus WCMRCoreAudioDevice::GetStreamLatency(AudioDeviceID device, bool isInpu
//! \return Nothing.
//!
//**********************************************************************************************
WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter
, bool useMultithreading, eCABS_Method eCABS_method, bool bNocopy)
: WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter
)
, m_UpdateDeviceListRequested(0)
, m_UpdateDeviceListProcessed(0)
WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient,
eAudioDeviceFilter eCurAudioDeviceFilter, bool useMultithreading, bool bNocopy)
: WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter)
, m_UseMultithreading (useMultithreading)
, m_eCABS_Method(eCABS_method)
, m_bNoCopyAudioBuffer(bNocopy)
{
AUTO_FUNC_DEBUG;
@ -2347,13 +2316,13 @@ WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerCli
}
//add a listener to find out when devices change...
AudioHardwareAddPropertyListener (kAudioHardwarePropertyDevices, StaticPropertyChangeProc, this);
AudioHardwareAddPropertyListener (kAudioHardwarePropertyDevices, DevicePropertyChangeCallback, this);
//Always add the None device first...
m_Devices.push_back (new WCMRNativeAudioNoneDevice(this));
m_NoneDevice = new WCMRNativeAudioNoneDevice(this);
//prepare our initial list...
UpdateDeviceList_Private();
generateDeviceListImpl();
return;
}
@ -2376,25 +2345,7 @@ WCMRCoreAudioDeviceManager::~WCMRCoreAudioDeviceManager()
try
{
AudioHardwareRemovePropertyListener (kAudioHardwarePropertyDevices, StaticPropertyChangeProc);
//Note: We purposely release the device list here, instead of
//depending on the superclass to do it, as by the time the superclass'
//destructor executes, we will have called Pa_Terminate()!
//Need to call release on our devices, and erase them from list
std::vector<WCMRAudioDevice*>::iterator deviceIter;
while (m_Devices.size())
{
WCMRAudioDevice *pDeviceToRelease = m_Devices.back();
m_Devices.pop_back();
SAFE_RELEASE (pDeviceToRelease);
}
//The derived classes may want to do additional de-int!
delete m_NoneDevice;
}
catch (...)
{
@ -2405,313 +2356,511 @@ WCMRCoreAudioDeviceManager::~WCMRCoreAudioDeviceManager()
}
//**********************************************************************************************
// WCMRCoreAudioDeviceManager::StaticPropertyChangeProc
//
//! The property change listener for the Audio Device Manager. It calls upon (non-static) PropertyChangeProc
//! to do the actual work.
//!
//! \param iPropertyID : the property that has changed.
//! \param inClientData : What was supplied at init time.
//!
//! \return if parameters are incorrect, or the value returned by PropertyChangeProc.
//!
//**********************************************************************************************
OSStatus WCMRCoreAudioDeviceManager::StaticPropertyChangeProc (AudioHardwarePropertyID inPropertyID, void* inClientData)
WCMRAudioDevice* WCMRCoreAudioDeviceManager::initNewCurrentDeviceImpl(const std::string & deviceName)
{
WCMRCoreAudioDeviceManager *pMyManager = (WCMRCoreAudioDeviceManager *)inClientData;
destroyCurrentDeviceImpl();
if (pMyManager)
return pMyManager->PropertyChangeProc (inPropertyID);
return 0;
std::cout << "API::PortAudioDeviceManager::initNewCurrentDevice " << deviceName << std::endl;
if (deviceName == m_NoneDevice->DeviceName() )
{
m_CurrentDevice = m_NoneDevice;
return m_CurrentDevice;
}
DeviceInfo devInfo;
WTErr err = GetDeviceInfoByName(deviceName, devInfo);
if (eNoErr == err)
{
try
{
std::cout << "API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName << std::endl;
TRACE_MSG ("API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName);
m_CurrentDevice = new WCMRCoreAudioDevice (this, devInfo.m_DeviceId, m_UseMultithreading, m_bNoCopyAudioBuffer);
}
catch (...)
{
std::cout << "Unabled to create PA Device: " << devInfo.m_DeviceId << std::endl;
DEBUG_MSG ("Unabled to create PA Device: " << devInfo.m_DeviceId);
}
}
return m_CurrentDevice;
}
//**********************************************************************************************
// WCMRCoreAudioDeviceManager::PropertyChangeProc
//
//! The property change listener for the Audio Device Manager. Currently we only listen for the
//! device list change (device arrival/removal, and accordingly cause an update to the device list.
//! Note that the actual update happens from the DoIdle() call to prevent multi-threading related issues.
//!
//! \param
//!
//! \return Nothing.
//!
//**********************************************************************************************
OSStatus WCMRCoreAudioDeviceManager::PropertyChangeProc (AudioHardwarePropertyID inPropertyID)
void WCMRCoreAudioDeviceManager::destroyCurrentDeviceImpl()
{
OSStatus retVal = 0;
switch (inPropertyID)
if (m_CurrentDevice != m_NoneDevice)
delete m_CurrentDevice;
m_CurrentDevice = 0;
}
WTErr WCMRCoreAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates)
{
AUTO_FUNC_DEBUG;
WTErr retVal = eNoErr;
OSStatus err = kAudioHardwareNoError;
UInt32 propSize = 0;
sampleRates.clear();
//! 1. Get sample rate property size.
err = AudioDeviceGetPropertyInfo(deviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, NULL);
if (err == kAudioHardwareNoError)
{
case kAudioHardwarePropertyDevices:
m_UpdateDeviceListRequested++;
break;
default:
break;
//! 2. Get property: cannels output.
// Allocate size accrding to the number of audio values
int numRates = propSize / sizeof(AudioValueRange);
AudioValueRange* supportedRates = new AudioValueRange[numRates];
// Get sampling rates from Audio device
err = AudioDeviceGetProperty(deviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, supportedRates);
if (err == kAudioHardwareNoError)
{
//! 3. Update sample rates
// now iterate through our standard SRs
for(int ourSR=0; gAllSampleRates[ourSR] > 0; ourSR++)
{
//check to see if our SR is in the supported rates...
for (int deviceSR = 0; deviceSR < numRates; deviceSR++)
{
if ((supportedRates[deviceSR].mMinimum <= gAllSampleRates[ourSR]) &&
(supportedRates[deviceSR].mMaximum >= gAllSampleRates[ourSR]))
{
sampleRates.push_back ((int)gAllSampleRates[ourSR]);
break;
}
}
}
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Sample rates. Device Name: " << m_DeviceName.c_str());
}
delete [] supportedRates;
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Sample rates property size. Device Name: " << m_DeviceName.c_str());
}
return retVal;
}
//**********************************************************************************************
// WCMRCoreAudioDeviceManager::remove_pattern
//
//! remove a substring from a given string
//!
//! \param original_str - original string
//! \param pattern_str - pattern to find
//! \param return_str - the return string - without the pattern substring
//!
//! \return Nothing.
//!
//**********************************************************************************************
void WCMRCoreAudioDeviceManager::remove_pattern(const std::string& original_str, const std::string& pattern_str, std::string& return_str)
{
char *orig_c_str = new char[original_str.size() + 1];
char* strSavePtr;
strcpy(orig_c_str, original_str.c_str());
char *p_splited_orig_str = strtok_r(orig_c_str," ", &strSavePtr);
std::ostringstream stream_str;
while (p_splited_orig_str != 0)
WTErr WCMRCoreAudioDeviceManager::getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels)
{
AUTO_FUNC_DEBUG;
WTErr retVal = eNoErr;
OSStatus err = kAudioHardwareNoError;
UInt32 propSize = 0;
inputChannels = 0;
// 1. Get property cannels input size.
err = AudioDeviceGetPropertyInfo (deviceId, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL);
if (err == kAudioHardwareNoError)
{
int cmp_res = strcmp(p_splited_orig_str, pattern_str.c_str()); // might need Ignore case ( stricmp OR strcasecmp)
if ( cmp_res != 0)
stream_str << p_splited_orig_str << " ";
p_splited_orig_str = strtok_r(NULL," ", &strSavePtr);
//! 2. Get property: cannels input.
// Allocate size according to the property size. Note that this is a variable sized struct...
AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize);
if (pStreamBuffers)
{
memset (pStreamBuffers, 0, propSize);
// Get the Input channels
err = AudioDeviceGetProperty (deviceId, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers);
if (err == kAudioHardwareNoError)
{
// Calculate the number of input channels
for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++)
{
inputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels;
}
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Input channels. Device Name: " << m_DeviceName.c_str());
}
free (pStreamBuffers);
}
else
{
retVal = eMemOutOfMemory;
DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str());
}
}
delete[] orig_c_str;
return_str = stream_str.str();
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Input channels property size. Device Name: " << m_DeviceName.c_str());
}
return retVal;
}
//**********************************************************************************************
// WCMRCoreAudioDeviceManager::UpdateDeviceList_Private
//
//! Updates the list of devices maintained by the manager. If devices have gone away, they are removed
//! if new devices have been connected, they are added to the list.
//!
//! \param none
//!
//! \return eNoErr on success, an error code on failure.
//!
//**********************************************************************************************
WTErr WCMRCoreAudioDeviceManager::UpdateDeviceList_Private()
WTErr WCMRCoreAudioDeviceManager::getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels)
{
AUTO_FUNC_DEBUG;
WTErr retVal = eNoErr;
OSStatus err = kAudioHardwareNoError;
UInt32 propSize = 0;
outputChannels = 0;
//! 1. Get property cannels output size.
err = AudioDeviceGetPropertyInfo (deviceId, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL);
if (err == kAudioHardwareNoError)
{
//! 2. Get property: cannels output.
// Allocate size according to the property size. Note that this is a variable sized struct...
AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize);
if (pStreamBuffers)
{
memset (pStreamBuffers, 0, propSize);
// Get the Output channels
err = AudioDeviceGetProperty (deviceId, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers);
if (err == kAudioHardwareNoError)
{
// Calculate the number of output channels
for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++)
{
outputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels;
}
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Output channels. Device Name: " << m_DeviceName.c_str());
}
free (pStreamBuffers);
}
else
{
retVal = eMemOutOfMemory;
DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str());
}
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device Output channels property size. Device Name: " << m_DeviceName.c_str());
}
return retVal;
}
WTErr WCMRCoreAudioDeviceManager::generateDeviceListImpl()
{
AUTO_FUNC_DEBUG;
// lock the list first
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
m_DeviceInfoVec.clear();
//First, get info from None device which is always present
if (m_NoneDevice)
{
DeviceInfo *pDevInfo = new DeviceInfo(NONE_DEVICE_ID, m_NoneDevice->DeviceName() );
pDevInfo->m_AvailableSampleRates = m_NoneDevice->SamplingRates();
m_DeviceInfoVec.push_back(pDevInfo);
}
WTErr retVal = eNoErr;
OSStatus osErr = noErr;
AudioDeviceID* deviceIDs = 0;
size_t reportedDeviceIndex = 0;
openlog("WCMRCoreAudioDeviceManager", LOG_PID | LOG_CONS, LOG_USER);
try
try
{
// Define 2 vectors for input and output - only for eMatchedDuplexDevices case
WCMRAudioDeviceList adOnlyIn;
WCMRAudioDeviceList adOnlyOut;
//Get device count...
UInt32 propSize = 0;
osErr = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &propSize, NULL);
ASSERT_ERROR(osErr, "AudioHardwareGetProperty 1");
if (WUIsError(osErr))
throw osErr;
size_t numDevices = propSize / sizeof (AudioDeviceID);
deviceIDs = new AudioDeviceID[numDevices];
//retrieve the device IDs
propSize = numDevices * sizeof (AudioDeviceID);
osErr = AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &propSize, deviceIDs);
ASSERT_ERROR(osErr, "Error while getting audio devices: AudioHardwareGetProperty 2");
if (WUIsError(osErr))
throw osErr;
//first go through our list of devices, remove the ones that are no longer present...
std::vector<WCMRAudioDevice*>::iterator deviceIter;
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); /*This is purposefully blank*/)
{
WCMRCoreAudioDevice *pDeviceToWorkUpon = dynamic_cast<WCMRCoreAudioDevice *>(*deviceIter);
//it's possible that the device is actually not a core audio device - perhaps a none device...
if (!pDeviceToWorkUpon)
{
deviceIter++;
continue;
}
AudioDeviceID myDeviceID = pDeviceToWorkUpon->DeviceID();
bool deviceFound = false;
for (reportedDeviceIndex = 0; reportedDeviceIndex < numDevices; reportedDeviceIndex++)
{
if (myDeviceID == deviceIDs[reportedDeviceIndex])
{
deviceFound = true;
break;
}
}
if (!deviceFound)
//now add the ones that are not there...
for (size_t deviceIndex = 0; deviceIndex < numDevices; deviceIndex++)
{
DeviceInfo* pDevInfo = 0;
//Get device name and create new DeviceInfo entry
//Get property name size.
osErr = AudioDeviceGetPropertyInfo(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL);
if (osErr == kAudioHardwareNoError)
{
//it's no longer there, need to remove it!
WCMRAudioDevice *pTheDeviceToErase = *deviceIter;
deviceIter = m_Devices.erase (deviceIter);
if (pTheDeviceToErase->Active())
//Get property: name.
char* deviceName = new char[propSize];
osErr = AudioDeviceGetProperty(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName);
if (osErr == kAudioHardwareNoError)
{
NotifyClient (WCMRAudioDeviceManagerClient::DeviceConnectionLost);
pDevInfo = new DeviceInfo(deviceIDs[deviceIndex], deviceName);
}
SAFE_RELEASE (pTheDeviceToErase);
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID);
}
delete [] deviceName;
}
else
deviceIter++;
}
//now add the ones that are not there...
for (reportedDeviceIndex = 0; reportedDeviceIndex < numDevices; reportedDeviceIndex++)
{
bool deviceFound = false;
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
{
WCMRCoreAudioDevice *pDeviceToWorkUpon = dynamic_cast<WCMRCoreAudioDevice *>(*deviceIter);
//it's possible that the device is actually not a core audio device - perhaps a none device...
if (!pDeviceToWorkUpon)
continue;
if (pDeviceToWorkUpon->DeviceID() == deviceIDs[reportedDeviceIndex])
{
deviceFound = true;
break;
}
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device name property size. Device ID: " << m_DeviceID);
}
if (!deviceFound)
if (pDevInfo)
{
//add it to our list...
//build a device object...
WCMRCoreAudioDevice *pNewDevice = new WCMRCoreAudioDevice (this, deviceIDs[reportedDeviceIndex], m_UseMultithreading, m_bNoCopyAudioBuffer);
bool bDeleteNewDevice = true;
//Retrieve all the information we need for the device
WTErr wErr = eNoErr;
if (pNewDevice)
//Get available sample rates for the device
std::vector<int> availableSampleRates;
wErr = getDeviceAvailableSampleRates(pDevInfo->m_DeviceId, availableSampleRates);
if (wErr != eNoErr)
{
DEBUG_MSG ("Failed to get device available sample rates. Device ID: " << m_DeviceID);
delete pDevInfo;
continue; //proceed to the next device
}
pDevInfo->m_AvailableSampleRates = availableSampleRates;
//Get max input channels
uint32 maxInputChannels;
wErr = getDeviceMaxInputChannels(pDevInfo->m_DeviceId, maxInputChannels);
if (wErr != eNoErr)
{
DEBUG_MSG ("Failed to get device max input channels count. Device ID: " << m_DeviceID);
delete pDevInfo;
continue; //proceed to the next device
}
pDevInfo->m_MaxInputChannels = maxInputChannels;
//Get max output channels
uint32 maxOutputChannels;
wErr = getDeviceMaxOutputChannels(pDevInfo->m_DeviceId, maxOutputChannels);
if (wErr != eNoErr)
{
DEBUG_MSG ("Failed to get device max output channels count. Device ID: " << m_DeviceID);
delete pDevInfo;
continue; //proceed to the next device
}
pDevInfo->m_MaxOutputChannels = maxOutputChannels;
//Now check if this device is acceptable according to current input/output settings
bool bRejectDevice = false;
switch(m_eAudioDeviceFilter)
{
// Don't delete the new device by default, since most cases use it
bDeleteNewDevice = false;
// Insert the new device to the device list according to its enum
switch(m_eAudioDeviceFilter)
{
case eInputOnlyDevices:
if ((int) pNewDevice->InputChannels().size() != 0)
if (pDevInfo->m_MaxInputChannels != 0)
{
m_Devices.push_back (pNewDevice);
m_DeviceInfoVec.push_back(pDevInfo);
}
else
{
// Delete unnecesarry device
bDeleteNewDevice = true;
bRejectDevice = true;
}
break;
case eOutputOnlyDevices:
if ((int) pNewDevice->OutputChannels().size() != 0)
if (pDevInfo->m_MaxOutputChannels != 0)
{
m_Devices.push_back (pNewDevice);
m_DeviceInfoVec.push_back(pDevInfo);
}
else
{
// Delete unnecesarry device
bDeleteNewDevice = true;
bRejectDevice = true;
}
break;
case eFullDuplexDevices:
if ((int) pNewDevice->InputChannels().size() != 0 && (int) pNewDevice->OutputChannels().size() != 0)
if (pDevInfo->m_MaxInputChannels != 0 && pDevInfo->m_MaxOutputChannels != 0)
{
m_Devices.push_back (pNewDevice);
m_DeviceInfoVec.push_back(pDevInfo);
}
else
{
// Delete unnecesarry device
bDeleteNewDevice = true;
bRejectDevice = true;
}
break;
case eAllDevices:
default:
m_Devices.push_back (pNewDevice);
m_DeviceInfoVec.push_back(pDevInfo);
break;
}
}
if(bDeleteNewDevice)
if(bRejectDevice)
{
syslog (LOG_NOTICE, "%s rejected, In Channels = %d, Out Channels = %d\n",
pNewDevice->DeviceName().c_str(), (int) pNewDevice->InputChannels().size(),
(int) pNewDevice->OutputChannels().size());
pDevInfo->m_DeviceName.c_str(), pDevInfo->m_MaxInputChannels, pDevInfo->m_MaxOutputChannels);
// In case of Input and Output both channels being Zero, we will release memory; since we created CoreAudioDevice but we are Not adding it in list.
SAFE_RELEASE(pNewDevice);
delete pDevInfo;
}
}
}
//If no devices were found, that's not a good thing!
if (m_Devices.empty())
if (m_DeviceInfoVec.empty())
{
DEBUG_MSG ("No matching CoreAudio devices were found\n");
}
m_UpdateDeviceListRequested = m_UpdateDeviceListProcessed = 0;
}
}
catch (...)
{
if (WUNoError(retVal))
retVal = eCoreAudioFailed;
}
safe_delete_array(deviceIDs);
delete[] deviceIDs;
closelog();
return retVal;
}
//**********************************************************************************************
// WCMRCoreAudioDeviceManager::DoIdle
//
//! Used for idle time processing. This calls each device's DoIdle so that it can perform it's own idle processing.
//! Also, if a device list change is detected, it updates the device list.
//!
//! \param none
//!
//! \return noErr if no devices have returned an error. An error code if any of the devices returned error.
//!
//**********************************************************************************************
WTErr WCMRCoreAudioDeviceManager::DoIdle()
WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl()
{
//WTErr retVal = eNoErr;
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
WTErr err = generateDeviceListImpl();
if (eNoErr != err)
{
//wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
//If there's something specific to CoreAudio manager idle handling do it here...
if (m_UpdateDeviceListRequested != m_UpdateDeviceListProcessed)
std::cout << "API::PortAudioDeviceManager::updateDeviceListImpl: Device list update error: "<< err << std::endl;
return err;
}
if (m_CurrentDevice)
{
// if we have device initialized we should find out if this device is still connected
DeviceInfo devInfo;
WTErr deviceLookUpErr = GetDeviceInfoByName(m_CurrentDevice->DeviceName(), devInfo );
if (eNoErr != deviceLookUpErr)
{
m_UpdateDeviceListProcessed = m_UpdateDeviceListRequested;
UpdateDeviceList_Private();
NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);
NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected);
return err;
}
}
//Note that the superclass is going to call all the devices' DoIdle() anyway...
return (WCMRAudioDeviceManager::DoIdle());
}
NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);
return err;
}
WTErr WCMRCoreAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const
{
AUTO_FUNC_DEBUG;
WTErr retVal = eNoErr;
OSStatus err = kAudioHardwareNoError;
UInt32 propSize = 0;
bufferSizes.clear();
//first check if the request has been made for None device
if (deviceName == m_NoneDevice->DeviceName() )
{
bufferSizes = m_NoneDevice->BufferSizes();
return retVal;
}
DeviceInfo devInfo;
retVal = GetDeviceInfoByName(deviceName, devInfo);
if (eNoErr == retVal)
{
// 1. Get buffer size range
AudioValueRange bufferSizesRange;
propSize = sizeof (AudioValueRange);
err = AudioDeviceGetProperty (devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &bufferSizesRange);
if(err == kAudioHardwareNoError)
{
// 2. Run on all ranges and add them to the list
for(int bsize=0; gAllBufferSizes[bsize] > 0; bsize++)
{
if ((bufferSizesRange.mMinimum <= gAllBufferSizes[bsize]) && (bufferSizesRange.mMaximum >= gAllBufferSizes[bsize]))
{
bufferSizes.push_back (gAllBufferSizes[bsize]);
}
}
//if we didn't get a single hit, let's simply add the min. and the max...
if (bufferSizes.empty())
{
bufferSizes.push_back ((int)bufferSizesRange.mMinimum);
bufferSizes.push_back ((int)bufferSizesRange.mMaximum);
}
}
else
{
retVal = eCoreAudioFailed;
DEBUG_MSG("Failed to get device buffer sizes range. Device Name: " << m_DeviceName.c_str());
}
}
else
{
retVal = eRMResNotFound;
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
}
return retVal;
}
OSStatus WCMRCoreAudioDeviceManager::DevicePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData)
{
switch (inPropertyID)
{
case kAudioHardwarePropertyDevices:
{
WCMRCoreAudioDeviceManager* pManager = (WCMRCoreAudioDeviceManager*)inClientData;
if (pManager)
pManager->updateDeviceListImpl();
}
break;
default:
break;
}
return 0;
}

View file

@ -1,23 +1,6 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRCoreAudioDeviceManager.h
//!
@ -138,7 +121,7 @@ protected:
uint32_t m_NextSampleToUse;
#endif //WV_USE_TONE_GEN
WTErr UpdateDeviceInfo (bool updateSRSupported, bool updateBufferSizes);
WTErr UpdateDeviceInfo ();
WTErr UpdateDeviceName();
WTErr UpdateDeviceInputs();
WTErr UpdateDeviceOutputs();
@ -181,40 +164,28 @@ class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
public:
WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
bool useMultithreading = true, eCABS_Method eCABS_method = eCABS_Simple, bool bNocopy = false); ///< constructor
bool useMultithreading = true, bool bNocopy = false); ///< constructor
virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
virtual WTErr UpdateDeviceList() //has to be overridden!
{
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
return UpdateDeviceList_Private();
}
virtual eCABS_Method GetBufferSizeMethod()
{
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
return GetBufferSizeMethod_Private();
}
virtual WTErr DoIdle();
private:
WTErr UpdateDeviceList_Private();
eCABS_Method GetBufferSizeMethod_Private() { return m_eCABS_Method; }
protected:
int m_UpdateDeviceListRequested; ///< Number of times device list change has been detected.
int m_UpdateDeviceListProcessed; ///< Number of times device list change has been processed.
static OSStatus DevicePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
virtual void destroyCurrentDeviceImpl();
virtual WTErr generateDeviceListImpl();
virtual WTErr updateDeviceListImpl();
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
bool m_bNoCopyAudioBuffer;
eCABS_Method m_eCABS_Method; // Type of core audio buffer size list method
static OSStatus StaticPropertyChangeProc (AudioHardwarePropertyID inPropertyID, void* inClientData);
OSStatus PropertyChangeProc (AudioHardwarePropertyID inPropertyID);
void remove_pattern(const std::string& original_str, const std::string& pattern_str, std::string& return_str);
private:
// helper functions for this class only
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
WTErr getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels);
WTErr getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels);
WCMRAudioDevice* m_NoneDevice;
};
#endif //#ifndef __WCMRCoreAudioDeviceManager_h_

View file

@ -1,23 +1,6 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRNativeAudio.cpp
//!
@ -136,6 +119,12 @@ WTErr WCMRNativeAudioNoneDevice::SetCurrentBufferSize (int newSize)
}
WTErr WCMRNativeAudioNoneDevice::UpdateDeviceInfo ()
{
return eNoErr;
}
WTErr WCMRNativeAudioNoneDevice::SetStreaming (bool newState)
{
if (Streaming() == newState)
@ -144,7 +133,8 @@ WTErr WCMRNativeAudioNoneDevice::SetStreaming (bool newState)
}
WCMRAudioDevice::SetStreaming(newState);
if(Streaming())
if (Streaming())
{
if (m_SilenceThread)
std::cerr << "\t\t\t\t\t !!!!!!!!!!!!!!! Warning: the inactive NONE-DEVICE was streaming!" << std::endl;

View file

@ -1,23 +1,6 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRNativeAudio.h
//!
@ -42,9 +25,10 @@ class WCMRNativeAudioDevice : public WCMRAudioDevice
{
public:
WCMRNativeAudioDevice (WCMRAudioDeviceManager *pManager, bool useMultithreading = true, bool bNoCopy = false) : WCMRAudioDevice (pManager),
m_UseMultithreading (useMultithreading),
m_bNoCopyAudioBuffer(bNoCopy)
WCMRNativeAudioDevice (WCMRAudioDeviceManager *pManager, bool useMultithreading = true, bool bNoCopy = false) :
WCMRAudioDevice (pManager)
, m_UseMultithreading (useMultithreading)
, m_bNoCopyAudioBuffer(bNoCopy)
{}
virtual ~WCMRNativeAudioDevice () {}
@ -52,7 +36,6 @@ protected:
bool m_UseMultithreading;
bool m_bNoCopyAudioBuffer; ///< This flag determines whether the audio callback performs a copy of audio, or the source/sink perform the copy. It should be true to let source/sink do the copies.
};
@ -65,6 +48,7 @@ public:
virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
virtual WTErr UpdateDeviceInfo ();
private:
@ -75,11 +59,11 @@ private:
#else
inline void _usleep(uint64_t usec) { ::usleep(usec); }
#endif
static const size_t __m_NumInputChannels = 32;
static const size_t __m_NumOutputChannels = 32;
static const size_t __m_NumInputChannels = 0;
static const size_t __m_NumOutputChannels = 0;
pthread_t m_SilenceThread;
float *_m_inputBuffer;
float *_m_outputBuffer;
float *_m_inputBuffer;
float *_m_outputBuffer;
static uint64_t __get_time_nanos ();
#if defined (_WINDOWS)
HANDLE _waitableTimerForUsleep;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,160 @@
//----------------------------------------------------------------------------------
//
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRPortAudioDeviceManager.h
//!
//! WCMRPortAudioDeviceManager and related class declarations
//!
//---------------------------------------------------------------------------------*/
#ifndef __WCMRPortAudioDeviceManager_h_
#define __WCMRPortAudioDeviceManager_h_
#include "WCMRAudioDeviceManager.h"
#include "WCMRNativeAudio.h"
#include "portaudio.h"
//forward decl.
class WCMRPortAudioDeviceManager;
//! Manages a port audio device, providing information
//! about the device, and managing audio callbacks.
class WCMRPortAudioDevice : public WCMRNativeAudioDevice
{
public:
WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int deviceID, bool useMultiThreading = true, bool bNoCopy = false);///<Constructor
virtual ~WCMRPortAudioDevice ();///<Destructor
virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
virtual int AudioCallback (const float *pInputBuffer, float *pOutputBuffer, unsigned long framesPerBuffe, bool dropsDetectedr);
virtual WTErr UpdateDeviceInfo ();
virtual WTErr ResetDevice();
#ifdef _WINDOWS
static long StaticASIOMessageHook (void *pRefCon, long selector, long value, void* message, double* opt);
long ASIOMessageHook (long selector, long value, void* message, double* opt);
#endif //_WINDOWS
protected:
static DWORD WINAPI __DoIdle__(LPVOID lpThreadParameter);
// Methods which are executed by device processing thread
WTErr DoIdle();///<Do Idle Processing
void initDevice();
void terminateDevice();
void updateDeviceInfo(bool callerIsWaiting = false);
void activateDevice(bool callerIsWaiting = false);
void deactivateDevice(bool callerIsWaiting = false);
void startStreaming(bool callerIsWaiting = false);
void stopStreaming(bool callerIsWaiting = false);
void resetDevice (bool callerIsWaiting = false);///<Reset device - close and reopen stream, update device information!
PaError testStateValidness(int sampleRate, int bufferSize);
///////////////////////////////////////////////////////////
static int TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* /*pTimeInfo*/, PaStreamCallbackFlags /*statusFlags*/, void *pUserData );
unsigned int m_DeviceID; ///< The PA device id
PaStream* m_PortAudioStream; ///< Port audio stream, when the device is active!
bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
const float *m_pInputData; ///< This is what came in with the most recent callback.
int m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
int m_SampleCountAtLastIdle;
int m_DropsDetected; ///< Number of times audio drops have been detected so far.
int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
int m_BufferSizeChangeRequested;
int m_BufferSizeChangeReported;
int m_ResetRequested;
int m_ResetReported;
int m_ResyncRequested;
int m_ResyncReported;
HANDLE m_hDeviceProcessingThread;
DWORD m_DeviceProcessingThreadID;
///< Backend request events
HANDLE m_hResetRequestedEvent;
HANDLE m_hResetDone;
HANDLE m_hUpdateDeviceInfoRequestedEvent;
HANDLE m_hUpdateDeviceInfoDone;
HANDLE m_hActivateRequestedEvent;
HANDLE m_hActivationDone;
HANDLE m_hDeActivateRequestedEvent;
HANDLE m_hDeActivationDone;
HANDLE m_hStartStreamingRequestedEvent;
HANDLE m_hStartStreamingDone;
HANDLE m_hStopStreamingRequestedEvent;
HANDLE m_hStopStreamingDone;
/////////////////////////
///< Device request events
HANDLE m_hResetFromDevRequestedEvent;
HANDLE m_hBufferSizeChangedEvent;
HANDLE m_hSampleRateChangedEvent;
/////////////////////////////
///< Sync events
HANDLE m_hDeviceInitialized;
HANDLE m_hExitIdleThread;
//Should be set if the device connection status is "DeviceErrors"
WTErr m_lastErr;
};
//! WCMRPortAudioDeviceManager
/*! The PortAudio Device Manager class */
class WCMRPortAudioDeviceManager : public WCMRAudioDeviceManager
{
public:
WCMRPortAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
bool useMultithreading = true, bool bNocopy = false); ///< constructor
virtual ~WCMRPortAudioDeviceManager(void); ///< destructor
protected:
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
virtual void destroyCurrentDeviceImpl();
virtual WTErr generateDeviceListImpl(); // use this in derived class to fill device list
virtual WTErr updateDeviceListImpl() {return eNoErr; } // not supported
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const;
bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
bool m_bNoCopyAudioBuffer;
private:
// helper functions for this class only
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
WCMRAudioDevice* m_NoneDevice;
};
#endif //#ifndef __WCMRPortAudioDeviceManager_h_

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __MinMaxUtilities_h__
#define __MinMaxUtilities_h__

View file

@ -1,87 +1,69 @@
#ifdef _WINDOWS
#include "IncludeWindows.h"
#endif
#if defined(__linux__) || defined(__MACOS__)
#include <sys/time.h>
#endif
#include "UMicroseconds.h"
namespace wvNS {
UMicroseconds& UMicroseconds::ReadTime()
{
#ifdef _WINDOWS
LARGE_INTEGER Frequency, Count ;
QueryPerformanceFrequency(&Frequency) ;
QueryPerformanceCounter(&Count);
theTime = uint64_t((Count.QuadPart * 1000000.0 / Frequency.QuadPart));
#endif
#if defined(__linux__) || defined(__MACOS__)
// Mac code replaced by posix calls, to reduce Carbon dependency.
timeval buf;
gettimeofday(&buf,NULL);
// micro sec
theTime = uint64_t(buf.tv_sec) * 1000*1000 + buf.tv_usec;
#endif
return *this;
}
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
Removed in favor of the posix implementation.
#ifdef __MACOS__
uint32_t UMicroseconds::hi() {return reinterpret_cast<UnsignedWide*>(&theTime)->hi;}
uint32_t UMicroseconds::lo() {return reinterpret_cast<UnsignedWide*>(&theTime)->lo;}
#endif
*/
#ifdef _WINDOWS
#include "IncludeWindows.h"
#endif
#if defined(__linux__) || defined(__MACOS__)
#include <sys/time.h>
#endif
#include "UMicroseconds.h"
namespace wvNS {
UMicroseconds& UMicroseconds::ReadTime()
{
#ifdef _WINDOWS
LARGE_INTEGER Frequency, Count ;
QueryPerformanceFrequency(&Frequency) ;
QueryPerformanceCounter(&Count);
theTime = uint64_t((Count.QuadPart * 1000000.0 / Frequency.QuadPart));
#endif
#if defined(__linux__) || defined(__MACOS__)
// Mac code replaced by posix calls, to reduce Carbon dependency.
timeval buf;
gettimeofday(&buf,NULL);
// micro sec
theTime = uint64_t(buf.tv_sec) * 1000*1000 + buf.tv_usec;
#endif
return *this;
}
/*
Removed in favor of the posix implementation.
#ifdef __MACOS__
uint32_t UMicroseconds::hi() {return reinterpret_cast<UnsignedWide*>(&theTime)->hi;}
uint32_t UMicroseconds::lo() {return reinterpret_cast<UnsignedWide*>(&theTime)->lo;}
#endif
*/
void UMicrosecondsAccumulator::Start()
{
m_start_time.ReadTime();
}
void UMicrosecondsAccumulator::Stop()
{
UMicroseconds stop_time;
m_accumulator += stop_time.GetNativeTime() - m_start_time.GetNativeTime();
}
void UMicrosecondsAccumulator::Clear()
{
m_start_time = 0;
m_accumulator = 0;
}
UMicroseconds UMicrosecondsAccumulator::GetAccumulatedTime() const
{
return m_accumulator;
}
UMicrosecondsAccumulator& UMicrosecondsAccumulator::operator+=(const UMicrosecondsAccumulator& inaccum_to_add)
{
m_accumulator += inaccum_to_add.GetAccumulatedTime();
return *this;
}
} // namespace wvNS {
void UMicrosecondsAccumulator::Start()
{
m_start_time.ReadTime();
}
void UMicrosecondsAccumulator::Stop()
{
UMicroseconds stop_time;
m_accumulator += stop_time.GetNativeTime() - m_start_time.GetNativeTime();
}
void UMicrosecondsAccumulator::Clear()
{
m_start_time = 0;
m_accumulator = 0;
}
UMicroseconds UMicrosecondsAccumulator::GetAccumulatedTime() const
{
return m_accumulator;
}
UMicrosecondsAccumulator& UMicrosecondsAccumulator::operator+=(const UMicrosecondsAccumulator& inaccum_to_add)
{
m_accumulator += inaccum_to_add.GetAccumulatedTime();
return *this;
}
} // namespace wvNS {

View file

@ -1,123 +1,105 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __UMicroseconds_h__
#define __UMicroseconds_h__
/* Copy to include
#include "UMicroseconds.h"
*/
#ifndef __UMicroseconds_h__
#define __UMicroseconds_h__
/* Copy to include
#include "UMicroseconds.h"
*/
#include "BasicTypes/WUDefines.h"
#include "BasicTypes/WUTypes.h"
namespace wvNS {
// a wraper for Microseconds function from Timer.h
class DllExport UMicroseconds
{
public:
#ifdef _WINDOWS
typedef int64_t TimeKeeper;
#endif
#ifdef __MACOS__
typedef uint64_t TimeKeeper;
#endif
#ifdef __linux__
typedef uint64_t TimeKeeper;
#endif
private:
TimeKeeper theTime;
public:
UMicroseconds()
{
ReadTime();
}
UMicroseconds(const TimeKeeper in_initVal) : theTime(in_initVal) {}
UMicroseconds(const UMicroseconds& inUM) : theTime(inUM.theTime) {}
UMicroseconds& operator=(const UMicroseconds& inUM) {theTime = inUM.theTime; return *this;}
UMicroseconds& operator+=(const TimeKeeper in_timeToAdd) {theTime += in_timeToAdd; return *this;}
UMicroseconds& ReadTime();
TimeKeeper GetNativeTime() const {return theTime;}
operator uint64_t () {return static_cast<uint64_t>(theTime);}
operator double () const {return static_cast<const double>(theTime);}
double Seconds() const {return static_cast<double>(theTime) / double(1000000);}
double MilliSeconds() const {return static_cast<double>(theTime) / double(1000);}
double MicroSeconds() const {return static_cast<double>(theTime);}
#ifdef __MACOS__
uint32_t hi();
uint32_t lo();
#endif
};
inline UMicroseconds operator-(const UMicroseconds& in_one, const UMicroseconds& in_two)
{
UMicroseconds retVal(in_one.GetNativeTime() - in_two.GetNativeTime());
return retVal;
}
class UMicrosecondsAccumulator
{
public:
UMicrosecondsAccumulator() : m_start_time(0), m_accumulator(0) {}
void Start();
void Stop();
void Clear();
UMicroseconds GetAccumulatedTime() const;
UMicrosecondsAccumulator& operator+=(const UMicrosecondsAccumulator&);
protected:
UMicroseconds m_start_time;
UMicroseconds m_accumulator;
};
inline UMicroseconds operator-(const UMicrosecondsAccumulator& in_one, const UMicrosecondsAccumulator& in_two)
{
UMicroseconds retVal(in_one.GetAccumulatedTime() - in_two.GetAccumulatedTime());
return retVal;
}
//=========================================================================================//
inline void MicrosecondDelay(double amt)
//=========================================================================================//
{
UMicroseconds than;
UMicroseconds now;
do
{
now.ReadTime();
} while ((now.MicroSeconds() - than.MicroSeconds()) < amt);
}
} // namespace wvNS {
#endif //#ifndef __UMicroseconds_h__
#include "BasicTypes/WUDefines.h"
#include "BasicTypes/WUTypes.h"
namespace wvNS {
// a wraper for Microseconds function from Timer.h
class DllExport UMicroseconds
{
public:
#ifdef _WINDOWS
typedef int64_t TimeKeeper;
#endif
#ifdef __MACOS__
typedef uint64_t TimeKeeper;
#endif
#ifdef __linux__
typedef uint64_t TimeKeeper;
#endif
private:
TimeKeeper theTime;
public:
UMicroseconds()
{
ReadTime();
}
UMicroseconds(const TimeKeeper in_initVal) : theTime(in_initVal) {}
UMicroseconds(const UMicroseconds& inUM) : theTime(inUM.theTime) {}
UMicroseconds& operator=(const UMicroseconds& inUM) {theTime = inUM.theTime; return *this;}
UMicroseconds& operator+=(const TimeKeeper in_timeToAdd) {theTime += in_timeToAdd; return *this;}
UMicroseconds& ReadTime();
TimeKeeper GetNativeTime() const {return theTime;}
operator uint64_t () {return static_cast<uint64_t>(theTime);}
operator double () const {return static_cast<const double>(theTime);}
double Seconds() const {return static_cast<double>(theTime) / double(1000000);}
double MilliSeconds() const {return static_cast<double>(theTime) / double(1000);}
double MicroSeconds() const {return static_cast<double>(theTime);}
#ifdef __MACOS__
uint32_t hi();
uint32_t lo();
#endif
};
inline UMicroseconds operator-(const UMicroseconds& in_one, const UMicroseconds& in_two)
{
UMicroseconds retVal(in_one.GetNativeTime() - in_two.GetNativeTime());
return retVal;
}
class UMicrosecondsAccumulator
{
public:
UMicrosecondsAccumulator() : m_start_time(0), m_accumulator(0) {}
void Start();
void Stop();
void Clear();
UMicroseconds GetAccumulatedTime() const;
UMicrosecondsAccumulator& operator+=(const UMicrosecondsAccumulator&);
protected:
UMicroseconds m_start_time;
UMicroseconds m_accumulator;
};
inline UMicroseconds operator-(const UMicrosecondsAccumulator& in_one, const UMicrosecondsAccumulator& in_two)
{
UMicroseconds retVal(in_one.GetAccumulatedTime() - in_two.GetAccumulatedTime());
return retVal;
}
//=========================================================================================//
inline void MicrosecondDelay(double amt)
//=========================================================================================//
{
UMicroseconds than;
UMicroseconds now;
do
{
now.ReadTime();
} while ((now.MicroSeconds() - than.MicroSeconds()) < amt);
}
} // namespace wvNS {
#endif //#ifndef __UMicroseconds_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WCFixedString_h__
#define __WCFixedString_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WUErrors_h__
#define __WUErrors_h__
@ -53,6 +35,7 @@ const WTErr eAppTerminateFailed = -23; //!< failed to terminate an appl
const WTErr eAppReturnedError = -24; //!< Non zero exit code from application
const WTErr eNotImplemented = -25; //!< Function is not implmemented
const WTErr eNotEmpty = -26; //!< Something was expected to be empty but is not
const WTErr eAsioFailed = -27;
// File Manager errors
const WTErr eFMNoSuchVolume = -1001;

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __safe_delete_h__
#define __safe_delete_h__

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
#include "WCRefManager.h"
/// Construcotr.

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 WCREFMANAGER_H
#define WCREFMANAGER_H

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
#include "Threads/WCThreadSafe.h"
#if XPLATFORMTHREADS_WINDOWS

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WCThreadSafe_h_
#define __WCThreadSafe_h_

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __WavesPublicAPI_Defines_h__
#define __WavesPublicAPI_Defines_h__

View file

@ -1,22 +1,5 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011 Waves Audio Ltd. All rights reserved.
// \file WTErr.h, defines basic error type and "No Error" code
// All users may use their own error codes with this type, as long as eNoErr remains defined here
///////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -1,21 +1,3 @@
/*
Copyright (C) 2013 Waves Audio Ltd.
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 __stdint_h__
#define __stdint_h__

83
libs/backends/wavesaudio/wscript Normal file → Executable file
View file

@ -19,14 +19,18 @@ def options(opt):
autowaf.set_options(opt)
def configure(conf):
if conf.options.dist_target == 'mingw':
autowaf.check_pkg(conf, 'portaudio-2.0', uselib_store='PORTAUDIO',
atleast_version='19')
autowaf.configure(conf)
def build(bld):
obj = bld(features = 'c cxx cxxshlib')
if bld.env['build_target'] == 'mountain_lion':
obj.framework = 'CoreMidi'
if bld.env['build_target'] == 'mingw':
obj = bld(features = 'cxx cxxshlib')
else:
obj.framework = 'CoreMIDI'
obj = bld(features = 'cxx cxxshlib', framework = ["CoreMidi"])
obj.source = [
'waves_audiobackend.cc',
'waves_audiobackend.latency.cc',
@ -41,34 +45,59 @@ def build(bld):
'waves_midi_buffer.cc',
'wavesapi/refmanager/WCRefManager.cpp',
'wavesapi/devicemanager/WCMRAudioDeviceManager.cpp',
'wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp',
'wavesapi/devicemanager/WCMRNativeAudio.cpp',
'wavesapi/threads/WCThreadSafe.cpp',
'portmidi/src/pm_common/pmutil.c',
'portmidi/src/pm_common/portmidi.c',
'portmidi/src/pm_mac/pmmac.c',
'portmidi/src/pm_mac/pmmacosxcm.c',
'portmidi/src/pm_mac/finddefault.c',
'portmidi/src/pm_mac/readbinaryplist.c',
'portmidi/src/porttime/ptmacosx_mach.c'
'portmidi/src/pm_common/pmutil.c',
'portmidi/src/pm_common/portmidi.c'
]
if bld.env['build_target'] == 'mingw':
platform_dependent = [
'wavesapi/miscutils/UMicroseconds.cpp',
'wavesapi/devicemanager/WCMRPortAudioDeviceManager.cpp',
'portmidi/src/pm_win/pmwin.c',
'portmidi/src/pm_win/pmwinmm.c',
'portmidi/src/porttime/ptwinmm.c'
]
else:
platform_dependent = [
'wavesapi/devicemanager/WCMRCoreAudioDeviceManager.cpp',
'portmidi/src/pm_mac/pmmac.c',
'portmidi/src/pm_mac/pmmacosxcm.c',
'portmidi/src/pm_mac/finddefault.c',
'portmidi/src/pm_mac/readbinaryplist.c',
'portmidi/src/porttime/ptmacosx_mach.c'
]
obj.source.extend(platform_dependent)
obj.includes = ['.',
'wavesapi',
'wavesapi/refmanager',
'wavesapi/wavespublicapi',
'wavesapi/devicemanager',
'wavesapi/miscutils',
'portmidi',
'portmidi/src/pm_common'
]
'wavesapi',
'wavesapi/refmanager',
'wavesapi/wavespublicapi',
'wavesapi/devicemanager',
'wavesapi/miscutils',
'wavesapi/threads',
'portmidi',
'portmidi/src/pm_common'
]
obj.cxxflags = [ '-fPIC' ]
obj.cflags = [ '-fPIC', '-fms-extensions' ]
obj.name = 'waves_audiobackend'
obj.target = 'waves_audiobackend'
obj.use = [ 'libardour', 'libpbd' ]
obj.use = 'libardour libpbd'
if bld.env['build_target'] == 'mingw':
obj.uselib = ['PORTAUDIO']
obj.vnum = WAVESAUDIOBACKEND_VERSION
obj.install_path = os.path.join(bld.env['LIBDIR'], 'backends')
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"',
'__MACOS__',
'ARDOURBACKEND_DLL_EXPORTS'
]
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3', 'backends')
if bld.env['build_target']== 'mingw':
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"',
'_WINDOWS',
'ARDOURBACKEND_DLL_EXPORTS'
]
else:
obj.defines = ['PACKAGE="' + I18N_PACKAGE + '"',
'__MACOS__',
'ARDOURBACKEND_DLL_EXPORTS'
]