Imported Upstream version 1.9.10+20140610git97e0e80b~dfsg
Adrian Knoth
9 years ago
0 | language: | |
1 | - cpp | |
2 | compiler: | |
3 | - gcc | |
4 | install: | |
5 | - sudo apt-get install libsamplerate-dev libsndfile-dev libasound2-dev | |
6 | script: | |
7 | - ./waf configure --alsa | |
8 | - ./waf build |
4 | 4 | LOCAL_PATH := $(call my-dir) |
5 | 5 | JACK_ROOT := $(call my-dir)/.. |
6 | 6 | SUPPORT_ALSA_IN_JACK := true |
7 | SUPPORT_ANDROID_REALTIME_SCHED := false | |
7 | 8 | ALSA_INCLUDES := vendor/samsung/common/external/alsa-lib/include |
8 | 9 | JACK_STL_LDFLAGS := -Lprebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI) -lgnustl_static |
9 | 10 | JACK_STL_INCLUDES := $(JACK_ROOT)/android/cxx-stl/gnu-libstdc++/libs/$(TARGET_CPU_ABI)/include \ |
237 | 238 | ../common/JackAudioAdapterFactory.cpp \ |
238 | 239 | ../linux/alsa/JackAlsaAdapter.cpp |
239 | 240 | |
241 | ifeq ($(SUPPORT_ANDROID_REALTIME_SCHED), true) | |
242 | sched_c_include := bionic/libc/bionic \ | |
243 | frameworks/av/services/audioflinger | |
244 | endif | |
245 | ||
240 | 246 | # ======================================================== |
241 | 247 | # libjackserver.so |
242 | 248 | # ======================================================== |
250 | 256 | LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libjackshm |
251 | 257 | LOCAL_MODULE_TAGS := eng optional |
252 | 258 | LOCAL_MODULE := libjackserver |
259 | ifeq ($(SUPPORT_ANDROID_REALTIME_SCHED), true) | |
260 | LOCAL_CFLAGS += -DJACK_ANDROID_REALTIME_SCHED | |
261 | LOCAL_C_INCLUDES += $(sched_c_include) | |
262 | LOCAL_SHARED_LIBRARIES += libbinder | |
263 | LOCAL_STATIC_LIBRARIES := libscheduling_policy | |
264 | endif | |
253 | 265 | |
254 | 266 | include $(BUILD_SHARED_LIBRARY) |
255 | 267 | |
282 | 294 | LOCAL_SHARED_LIBRARIES := libc libdl libcutils libutils libjackshm |
283 | 295 | LOCAL_MODULE_TAGS := eng optional |
284 | 296 | LOCAL_MODULE := libjack |
297 | ifeq ($(SUPPORT_ANDROID_REALTIME_SCHED), true) | |
298 | LOCAL_CFLAGS += -DJACK_ANDROID_REALTIME_SCHED | |
299 | LOCAL_C_INCLUDES += $(sched_c_include) | |
300 | LOCAL_SHARED_LIBRARIES += libbinder | |
301 | LOCAL_STATIC_LIBRARIES := libscheduling_policy | |
302 | endif | |
285 | 303 | |
286 | 304 | include $(BUILD_SHARED_LIBRARY) |
287 | 305 |
26 | 26 | #include <unistd.h> // for _POSIX_PRIORITY_SCHEDULING check |
27 | 27 | #include <signal.h> |
28 | 28 | |
29 | #ifdef JACK_ANDROID_REALTIME_SCHED | |
30 | #include "SchedulingPolicyService.h" | |
31 | #endif | |
32 | ||
29 | 33 | //#define JACK_SCHED_POLICY SCHED_RR |
30 | 34 | #define JACK_SCHED_POLICY SCHED_FIFO |
31 | 35 | |
240 | 244 | |
241 | 245 | jack_log("JackAndroidThread::AcquireRealTimeImp priority = %d", priority); |
242 | 246 | |
247 | #ifndef JACK_ANDROID_REALTIME_SCHED | |
243 | 248 | if ((res = pthread_setschedparam(thread, JACK_SCHED_POLICY, &rtparam)) != 0) { |
244 | 249 | jack_error("Cannot use real-time scheduling (RR/%d)" |
245 | 250 | "(%d: %s)", rtparam.sched_priority, res, |
246 | 251 | strerror(res)); |
247 | 252 | return -1; |
248 | 253 | } |
254 | #else | |
255 | if ((res = android::requestPriority(getpid(), gettid(), priority)) != 0) { | |
256 | jack_log("Failed to get SCHED_FIFO priority pid %d tid %d; error %d", | |
257 | getpid(), gettid(), res); | |
258 | return -1; | |
259 | } | |
260 | #endif | |
249 | 261 | return 0; |
250 | 262 | } |
251 | 263 |
25 | 25 | #include "JackGlobals.h" |
26 | 26 | #include "JackTime.h" |
27 | 27 | #include "JackPortType.h" |
28 | #include "JackMetadata.h" | |
28 | 29 | #include <math.h> |
29 | 30 | |
30 | 31 | using namespace Jack; |
36 | 37 | |
37 | 38 | typedef void (*print_function)(const char*); |
38 | 39 | typedef void *(*thread_routine)(void*); |
40 | ||
41 | LIB_EXPORT const char* JACK_METADATA_PRETTY_NAME = "http://jackaudio.org/metadata/pretty-name"; | |
42 | LIB_EXPORT const char* JACK_METADATA_HARDWARE = "http://jackaudio.org/metadata/hardware"; | |
43 | LIB_EXPORT const char* JACK_METADATA_CONNECTED = "http://jackaudio.org/metadata/connected"; | |
44 | LIB_EXPORT const char* JACK_METADATA_PORT_GROUP = "http://jackaudio.org/metadata/port-group"; | |
45 | LIB_EXPORT const char* JACK_METADATA_ICON_SMALL = "http://jackaudio.org/metadata/icon-small"; | |
46 | LIB_EXPORT const char* JACK_METADATA_ICON_LARGE = "http://jackaudio.org/metadata/icon-large"; | |
39 | 47 | |
40 | 48 | LIB_EXPORT |
41 | 49 | void |
121 | 129 | unsigned long buffer_size); |
122 | 130 | LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *); |
123 | 131 | LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t); |
132 | LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t*); | |
124 | 133 | LIB_EXPORT const char* jack_port_name(const jack_port_t *port); |
125 | 134 | LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port); |
126 | 135 | LIB_EXPORT int jack_port_flags(const jack_port_t *port); |
262 | 271 | LIB_EXPORT void jack_session_commands_free(jack_session_command_t *cmds); |
263 | 272 | LIB_EXPORT int jack_client_has_session_callback(jack_client_t *client, const char* client_name); |
264 | 273 | |
274 | LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type); | |
275 | LIB_EXPORT int jack_get_property(jack_uuid_t subject, const char* key, char** value, char** type); | |
276 | LIB_EXPORT void jack_free_description(jack_description_t* desc, int free_description_itself); | |
277 | LIB_EXPORT int jack_get_properties(jack_uuid_t subject, jack_description_t* desc); | |
278 | LIB_EXPORT int jack_get_all_properties(jack_description_t** descs); | |
279 | LIB_EXPORT int jack_remove_property(jack_client_t* client, jack_uuid_t subject, const char* key); | |
280 | LIB_EXPORT int jack_remove_properties(jack_client_t* client, jack_uuid_t subject); | |
281 | LIB_EXPORT int jack_remove_all_properties(jack_client_t* client); | |
282 | LIB_EXPORT int jack_set_property_change_callback(jack_client_t* client, JackPropertyChangeCallback callback, void* arg); | |
283 | ||
284 | LIB_EXPORT jack_uuid_t jack_client_uuid_generate(); | |
285 | LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t port_id); | |
286 | LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t); | |
287 | LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t); | |
288 | LIB_EXPORT void jack_uuid_copy(jack_uuid_t* dst, jack_uuid_t src); | |
289 | LIB_EXPORT void jack_uuid_clear(jack_uuid_t*); | |
290 | LIB_EXPORT int jack_uuid_parse(const char* buf, jack_uuid_t*); | |
291 | LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]); | |
292 | LIB_EXPORT int jack_uuid_empty(jack_uuid_t); | |
293 | ||
265 | 294 | #ifdef __cplusplus |
266 | 295 | } |
267 | 296 | #endif |
344 | 373 | } |
345 | 374 | } |
346 | 375 | |
376 | LIB_EXPORT jack_uuid_t jack_port_uuid(const jack_port_t*) | |
377 | { | |
378 | return 0; | |
379 | } | |
380 | ||
347 | 381 | LIB_EXPORT const char* jack_port_name(const jack_port_t* port) |
348 | 382 | { |
349 | 383 | JackGlobals::CheckContext("jack_port_name"); |
2030 | 2064 | return client->ClientHasSessionCallback(client_name); |
2031 | 2065 | } |
2032 | 2066 | } |
2067 | ||
2068 | LIB_EXPORT int jack_set_property(jack_client_t*, jack_uuid_t, const char*, const char*, const char*) | |
2069 | { | |
2070 | return -1; | |
2071 | } | |
2072 | ||
2073 | LIB_EXPORT int jack_get_property(jack_uuid_t, const char*, char**, char**) | |
2074 | { | |
2075 | return -1; | |
2076 | } | |
2077 | ||
2078 | LIB_EXPORT void jack_free_description(jack_description_t*, int) | |
2079 | { | |
2080 | } | |
2081 | ||
2082 | LIB_EXPORT int jack_get_properties(jack_uuid_t, jack_description_t*) | |
2083 | { | |
2084 | return -1; | |
2085 | } | |
2086 | ||
2087 | LIB_EXPORT int jack_get_all_properties(jack_description_t**) | |
2088 | { | |
2089 | return -1; | |
2090 | } | |
2091 | ||
2092 | LIB_EXPORT int jack_remove_property(jack_client_t*, jack_uuid_t, const char*) | |
2093 | { | |
2094 | return -1; | |
2095 | } | |
2096 | ||
2097 | LIB_EXPORT int jack_remove_properties(jack_client_t*, jack_uuid_t) | |
2098 | { | |
2099 | return -1; | |
2100 | } | |
2101 | ||
2102 | LIB_EXPORT int jack_remove_all_properties(jack_client_t*) | |
2103 | { | |
2104 | return -1; | |
2105 | } | |
2106 | ||
2107 | LIB_EXPORT int jack_set_property_change_callback(jack_client_t*, JackPropertyChangeCallback, void*) | |
2108 | { | |
2109 | return -1; | |
2110 | } | |
2111 | ||
2112 | LIB_EXPORT jack_uuid_t jack_client_uuid_generate() | |
2113 | { | |
2114 | return 0; | |
2115 | } | |
2116 | ||
2117 | LIB_EXPORT jack_uuid_t jack_port_uuid_generate(uint32_t) | |
2118 | { | |
2119 | return 0; | |
2120 | } | |
2121 | ||
2122 | LIB_EXPORT uint32_t jack_uuid_to_index(jack_uuid_t) | |
2123 | { | |
2124 | return 0; | |
2125 | } | |
2126 | ||
2127 | LIB_EXPORT int jack_uuid_compare(jack_uuid_t, jack_uuid_t) | |
2128 | { | |
2129 | return 0; | |
2130 | } | |
2131 | ||
2132 | LIB_EXPORT void jack_uuid_copy(jack_uuid_t*, jack_uuid_t) | |
2133 | { | |
2134 | } | |
2135 | ||
2136 | LIB_EXPORT void jack_uuid_clear(jack_uuid_t*) | |
2137 | { | |
2138 | } | |
2139 | ||
2140 | LIB_EXPORT int jack_uuid_parse(const char*, jack_uuid_t*) | |
2141 | { | |
2142 | return 0; | |
2143 | } | |
2144 | ||
2145 | LIB_EXPORT void jack_uuid_unparse(jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]) | |
2146 | { | |
2147 | } | |
2148 | ||
2149 | LIB_EXPORT int jack_uuid_empty(jack_uuid_t) | |
2150 | { | |
2151 | return 0; | |
2152 | } |
33 | 33 | #define JACK_SERVER_NAME_SIZE 256 |
34 | 34 | #define JACK_CLIENT_NAME_SIZE 64 |
35 | 35 | #define JACK_MESSAGE_SIZE 256 |
36 | #define JACK_UUID_SIZE 32 | |
36 | #define JACK_UUID_SIZE 36 // to match jack1 and uuid.h | |
37 | #define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ | |
37 | 38 | #define JACK_SESSION_COMMAND_SIZE 256 |
38 | 39 | |
39 | 40 | #define SYNC_MAX_NAME_SIZE 256 |
447 | 447 | JackDriverDescFunction so_get_descriptor = NULL; |
448 | 448 | char filename[1024]; |
449 | 449 | JSList* node; |
450 | void* dlhandle; | |
450 | void* dlhandle = NULL; | |
451 | 451 | |
452 | 452 | sprintf(filename, "%s/%s", driver_dir, sofile); |
453 | 453 | so_get_descriptor = (JackDriverDescFunction)check_symbol(sofile, symbol, driver_dir, &dlhandle); |
476 | 476 | strncpy(descriptor->file, filename, JACK_PATH_MAX); |
477 | 477 | |
478 | 478 | error: |
479 | ||
480 | UnloadDriverModule(dlhandle); | |
479 | if (dlhandle) { | |
480 | UnloadDriverModule(dlhandle); | |
481 | } | |
481 | 482 | return descriptor; |
482 | 483 | } |
483 | 484 |
0 | /* | |
1 | Copyright (C) 2011 David Robillard | |
2 | Copyright (C) 2013 Paul Davis | |
3 | ||
4 | This program is free software; you can redistribute it and/or modify it | |
5 | under the terms of the GNU Lesser General Public License as published by | |
6 | the Free Software Foundation; either version 2.1 of the License, or (at | |
7 | your option) any later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, but WITHOUT | |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
12 | License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public License | |
15 | along with this program; if not, write to the Free Software Foundation, | |
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 | */ | |
18 | ||
19 | #ifndef __jack_metadata_int_h__ | |
20 | #define __jack_metadata_int_h__ | |
21 | ||
22 | #include <stdint.h> | |
23 | ||
24 | #ifdef __cplusplus | |
25 | extern "C" { | |
26 | #endif | |
27 | ||
28 | typedef struct { | |
29 | const char* key; | |
30 | const char* data; | |
31 | const char* type; | |
32 | } jack_property_t; | |
33 | ||
34 | typedef struct { | |
35 | jack_uuid_t subject; | |
36 | uint32_t property_cnt; | |
37 | jack_property_t* properties; | |
38 | uint32_t property_size; | |
39 | } jack_description_t; | |
40 | ||
41 | typedef enum { | |
42 | PropertyCreated, | |
43 | PropertyChanged, | |
44 | PropertyDeleted | |
45 | } jack_property_change_t; | |
46 | ||
47 | typedef void (*JackPropertyChangeCallback)(jack_uuid_t subject, | |
48 | const char* key, | |
49 | jack_property_change_t change, | |
50 | void* arg); | |
51 | ||
52 | #ifdef __cplusplus | |
53 | } | |
54 | #endif | |
55 | #endif |
33 | 33 | write_pos = 0; |
34 | 34 | event_count = 0; |
35 | 35 | lost_events = 0; |
36 | mix_index = 0; | |
37 | 36 | } |
38 | 37 | |
39 | 38 | SERVER_EXPORT jack_shmsize_t JackMidiBuffer::MaxEventSize() const |
99 | 98 | } |
100 | 99 | mix->Reset(nframes); |
101 | 100 | |
101 | uint32_t mix_index[src_count]; | |
102 | 102 | int event_count = 0; |
103 | 103 | for (int i = 0; i < src_count; ++i) { |
104 | 104 | JackMidiBuffer* buf = static_cast<JackMidiBuffer*>(src_buffers[i]); |
106 | 106 | jack_error("Jack::MidiBufferMixdown - invalid source buffer"); |
107 | 107 | return; |
108 | 108 | } |
109 | buf->mix_index = 0; | |
109 | mix_index[i] = 0; | |
110 | 110 | event_count += buf->event_count; |
111 | 111 | mix->lost_events += buf->lost_events; |
112 | 112 | } |
115 | 115 | for (events_done = 0; events_done < event_count; ++events_done) { |
116 | 116 | JackMidiBuffer* next_buf = 0; |
117 | 117 | JackMidiEvent* next_event = 0; |
118 | uint32_t next_buf_index = 0; | |
118 | 119 | |
119 | 120 | // find the earliest event |
120 | 121 | for (int i = 0; i < src_count; ++i) { |
121 | 122 | JackMidiBuffer* buf = static_cast<JackMidiBuffer*>(src_buffers[i]); |
122 | if (buf->mix_index >= buf->event_count) | |
123 | if (mix_index[i] >= buf->event_count) | |
123 | 124 | continue; |
124 | JackMidiEvent* e = &buf->events[buf->mix_index]; | |
125 | JackMidiEvent* e = &buf->events[mix_index[i]]; | |
125 | 126 | if (!next_event || e->time < next_event->time) { |
126 | 127 | next_event = e; |
127 | 128 | next_buf = buf; |
129 | next_buf_index = i; | |
128 | 130 | } |
129 | 131 | } |
130 | 132 | assert(next_event != 0); |
131 | 133 | |
132 | 134 | // write the event |
133 | 135 | jack_midi_data_t* dest = mix->ReserveEvent(next_event->time, next_event->size); |
134 | if (!dest) { | |
135 | break; | |
136 | } | |
136 | if (!dest) break; | |
137 | ||
137 | 138 | memcpy(dest, next_event->GetData(next_buf), next_event->size); |
138 | next_buf->mix_index++; | |
139 | mix_index[next_buf_index]++; | |
139 | 140 | } |
140 | 141 | mix->lost_events += event_count - events_done; |
141 | 142 | } |
81 | 81 | jack_shmsize_t write_pos; //!< data write position from the end of the buffer. |
82 | 82 | uint32_t event_count; |
83 | 83 | uint32_t lost_events; |
84 | uint32_t mix_index; | |
85 | 84 | |
86 | 85 | JackMidiEvent events[1]; // Using 0 size does not compile with older GCC versions, so use 1 here. |
87 | 86 |
244 | 244 | } |
245 | 245 | } |
246 | 246 | |
247 | if (rx_bytes == sizeof(session_params_t )) { | |
247 | if (rx_bytes == sizeof(session_params_t)) { | |
248 | 248 | switch (GetPacketType(&fParams)) { |
249 | 249 | |
250 | 250 | case SLAVE_AVAILABLE: |
860 | 860 | // One cycle |
861 | 861 | Process(); |
862 | 862 | |
863 | // Then use PACKET_TIMEOUT for next cycles | |
864 | SetPacketTimeOut(PACKET_TIMEOUT); | |
863 | // Then use PACKET_TIMEOUT * fParams.fNetworkLatency for next cycles | |
864 | SetPacketTimeOut(PACKET_TIMEOUT * fParams.fNetworkLatency); | |
865 | 865 | } |
866 | 866 | |
867 | 867 | int Process() |
48 | 48 | fParams.fSampleRate = sample_rate; |
49 | 49 | fParams.fPeriodSize = buffer_size; |
50 | 50 | fParams.fSlaveSyncMode = 1; |
51 | fParams.fNetworkLatency = 2; | |
51 | fParams.fNetworkLatency = NETWORK_DEFAULT_LATENCY; | |
52 | 52 | fParams.fSampleEncoder = JackFloatEncoder; |
53 | 53 | fClient = jack_client; |
54 | 54 | |
352 | 352 | switch (SyncRecv()) { |
353 | 353 | |
354 | 354 | case SOCKET_ERROR: |
355 | return 0; | |
355 | return SOCKET_ERROR; | |
356 | 356 | |
357 | 357 | case SYNC_PACKET_ERROR: |
358 | 358 | // Since sync packet is incorrect, don't decode it and continue with data |
62 | 62 | fNetMidiPlaybackBuffer = NULL; |
63 | 63 | memset(&fSendTransportData, 0, sizeof(net_transport_data_t)); |
64 | 64 | memset(&fReturnTransportData, 0, sizeof(net_transport_data_t)); |
65 | fPacketTimeOut = PACKET_TIMEOUT; | |
65 | fPacketTimeOut = PACKET_TIMEOUT * NETWORK_DEFAULT_LATENCY; | |
66 | 66 | } |
67 | 67 | |
68 | 68 | void JackNetInterface::FreeNetworkBuffers() |
481 | 481 | // receive sync (launch the cycle) |
482 | 482 | do { |
483 | 483 | rx_bytes = Recv(fParams.fMtu, MSG_PEEK); |
484 | // connection issue, send will detect it, so don't skip the cycle (return 0) | |
484 | // connection issue (return -1) | |
485 | 485 | if (rx_bytes == SOCKET_ERROR) { |
486 | 486 | return SOCKET_ERROR; |
487 | 487 | } |
732 | 732 | return NET_RECV_ERROR; |
733 | 733 | } |
734 | 734 | } |
735 | while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0)); | |
735 | while (strcmp(host_params.fPacketType, fParams.fPacketType) && (GetPacketType(&host_params) != SLAVE_SETUP) && (--try_count > 0)); | |
736 | 736 | |
737 | 737 | // time out failure.. |
738 | 738 | if (try_count == 0) { |
742 | 742 | |
743 | 743 | // everything is OK, copy parameters |
744 | 744 | fParams = host_params; |
745 | ||
745 | ||
746 | 746 | // connect the socket |
747 | 747 | if (fSocket.Connect() == SOCKET_ERROR) { |
748 | 748 | jack_error("Error in connect : %s", StrError(NET_ERROR_CODE)); |
37 | 37 | #define SLAVE_INIT_TIMEOUT 1000000 * 1 // in usec |
38 | 38 | #define PACKET_TIMEOUT 500000 // in usec |
39 | 39 | |
40 | #define NETWORK_MAX_LATENCY 30 // maximum possible latency in network master/slave loop | |
40 | #define NETWORK_DEFAULT_LATENCY 2 | |
41 | #define NETWORK_MAX_LATENCY 30 // maximum possible latency in network master/slave loop | |
41 | 42 | |
42 | 43 | /** |
43 | 44 | \Brief This class describes the basic Net Interface, used by both master and slave. |
93 | 93 | NetMidiBuffer::NetMidiBuffer(session_params_t* params, uint32_t nports, char* net_buffer) |
94 | 94 | { |
95 | 95 | fNPorts = nports; |
96 | fMaxBufsize = fNPorts * sizeof(sample_t) * params->fPeriodSize ; | |
96 | fMaxBufsize = fNPorts * sizeof(sample_t) * params->fPeriodSize; | |
97 | 97 | fMaxPcktSize = params->fMtu - sizeof(packet_header_t); |
98 | 98 | fBuffer = new char[fMaxBufsize]; |
99 | 99 | fPortBuffer = new JackMidiBuffer* [fNPorts]; |
101 | 101 | fPortBuffer[port_index] = NULL; |
102 | 102 | } |
103 | 103 | fNetBuffer = net_buffer; |
104 | ||
105 | 104 | fCycleBytesSize = params->fMtu |
106 | 105 | * (max(params->fSendMidiChannels, params->fReturnMidiChannels) |
107 | 106 | * params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t))); |
1270 | 1269 | jack_info("Transport cycle state : %u", data->fState); |
1271 | 1270 | jack_info("**********************************************"); |
1272 | 1271 | } |
1273 | ||
1272 | ||
1274 | 1273 | SERVER_EXPORT void MidiBufferHToN(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer) |
1275 | 1274 | { |
1276 | 1275 | dst_buffer->magic = htonl(src_buffer->magic); |
1279 | 1278 | dst_buffer->write_pos = htonl(src_buffer->write_pos); |
1280 | 1279 | dst_buffer->event_count = htonl(src_buffer->event_count); |
1281 | 1280 | dst_buffer->lost_events = htonl(src_buffer->lost_events); |
1282 | dst_buffer->mix_index = htonl(src_buffer->mix_index); | |
1283 | 1281 | } |
1284 | 1282 | |
1285 | 1283 | SERVER_EXPORT void MidiBufferNToH(JackMidiBuffer* src_buffer, JackMidiBuffer* dst_buffer) |
1290 | 1288 | dst_buffer->write_pos = ntohl(src_buffer->write_pos); |
1291 | 1289 | dst_buffer->event_count = ntohl(src_buffer->event_count); |
1292 | 1290 | dst_buffer->lost_events = ntohl(src_buffer->lost_events); |
1293 | dst_buffer->mix_index = ntohl(src_buffer->mix_index); | |
1294 | 1291 | } |
1295 | 1292 | |
1296 | 1293 | SERVER_EXPORT void TransportDataHToN(net_transport_data_t* src_params, net_transport_data_t* dst_params) |
36 | 36 | |
37 | 37 | void JackTools::KillServer() |
38 | 38 | { |
39 | #ifdef WIN32 | |
39 | 40 | raise(SIGINT); |
41 | #else | |
42 | kill(GetPID(), SIGINT); | |
43 | #endif | |
40 | 44 | } |
41 | 45 | |
42 | 46 | void JackTools::ThrowJackNetException() |
147 | 147 | char * jack_get_client_name (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; |
148 | 148 | |
149 | 149 | /** |
150 | * Get the session ID for a client name. | |
151 | * | |
152 | * The session manager needs this to reassociate a client name to the session_id. | |
153 | * | |
154 | * The caller is responsible for calling jack_free(3) on any non-NULL | |
155 | * returned value. | |
156 | */ | |
157 | char *jack_get_uuid_for_client_name (jack_client_t *client, | |
158 | const char *client_name) JACK_WEAK_EXPORT; | |
159 | ||
160 | /** | |
161 | * Get the client name for a session_id. | |
162 | * | |
163 | * In order to snapshot the graph connections, the session manager needs to map | |
164 | * session_ids to client names. | |
165 | * | |
166 | * The caller is responsible for calling jack_free(3) on any non-NULL | |
167 | * returned value. | |
168 | */ | |
169 | char *jack_get_client_name_by_uuid (jack_client_t *client, | |
170 | const char *client_uuid ) JACK_WEAK_EXPORT; | |
171 | ||
172 | /** | |
150 | 173 | * Load an internal client into the Jack server. |
151 | 174 | * |
152 | 175 | * Internal clients run inside the JACK server process. They can use |
748 | 771 | * Port buffers have to be retrieved in each callback for proper functionning. |
749 | 772 | */ |
750 | 773 | void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; |
774 | ||
775 | /** | |
776 | * @return the UUID of the jack_port_t | |
777 | * | |
778 | * @see jack_uuid_to_string() to convert into a string representation | |
779 | */ | |
780 | jack_uuid_t jack_port_uuid (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; | |
751 | 781 | |
752 | 782 | /** |
753 | 783 | * @return the full name of the jack_port_t (including the @a |
0 | /* | |
1 | Copyright (C) 2011 David Robillard | |
2 | Copyright (C) 2013 Paul Davis | |
3 | ||
4 | This program is free software; you can redistribute it and/or modify it | |
5 | under the terms of the GNU Lesser General Public License as published by | |
6 | the Free Software Foundation; either version 2.1 of the License, or (at | |
7 | your option) any later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, but WITHOUT | |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
12 | License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public License | |
15 | along with this program; if not, write to the Free Software Foundation, | |
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 | */ | |
18 | ||
19 | /** | |
20 | * @file jack/metadata.h | |
21 | * @ingroup publicheader | |
22 | * @brief JACK Metadata API | |
23 | * | |
24 | */ | |
25 | ||
26 | #ifndef __jack_metadata_h__ | |
27 | #define __jack_metadata_h__ | |
28 | ||
29 | #include <jack/types.h> | |
30 | ||
31 | #ifdef __cplusplus | |
32 | extern "C" { | |
33 | #endif | |
34 | ||
35 | /** | |
36 | * @defgroup Metadata Metadata API. | |
37 | * @{ | |
38 | */ | |
39 | ||
40 | /** | |
41 | * A single property (key:value pair). | |
42 | */ | |
43 | typedef struct { | |
44 | /** The key of this property (URI string). */ | |
45 | const char* key; | |
46 | ||
47 | /** The property value (null-terminated string). */ | |
48 | const char* data; | |
49 | ||
50 | /** | |
51 | * Type of data, either a MIME type or URI. | |
52 | * | |
53 | * If type is NULL or empty, the data is assumed to be a UTF-8 encoded | |
54 | * string (text/plain). The data is a null-terminated string regardless of | |
55 | * type, so values can always be copied, but clients should not try to | |
56 | * interpret values of an unknown type. | |
57 | * | |
58 | * Example values: | |
59 | * - image/png;base64 (base64 encoded PNG image) | |
60 | * - http://www.w3.org/2001/XMLSchema#int (integer) | |
61 | * | |
62 | * Official types are preferred, but clients may use any syntactically | |
63 | * valid MIME type (which start with a type and slash, like "text/..."). | |
64 | * If a URI type is used, it must be a complete absolute URI | |
65 | * (which start with a scheme and colon, like "http:"). | |
66 | */ | |
67 | const char* type; | |
68 | } jack_property_t; | |
69 | ||
70 | /** | |
71 | * Set a property on @p subject. | |
72 | * | |
73 | * See the above documentation for rules about @p subject and @p key. | |
74 | * @param subject The subject to set the property on. | |
75 | * @param key The key of the property. | |
76 | * @param value The value of the property. | |
77 | * @param type The type of the property. See the discussion of | |
78 | * types in the definition of jack_property_t above. | |
79 | * @return 0 on success. | |
80 | */ | |
81 | int | |
82 | jack_set_property(jack_client_t*, | |
83 | jack_uuid_t subject, | |
84 | const char* key, | |
85 | const char* value, | |
86 | const char* type); | |
87 | ||
88 | /** | |
89 | * Get a property on @p subject. | |
90 | * | |
91 | * @param subject The subject to get the property from. | |
92 | * @param key The key of the property. | |
93 | * @param value Set to the value of the property if found, or NULL otherwise. | |
94 | * The caller must free this value with jack_free(). | |
95 | * @param type The type of the property if set, or NULL. See the discussion | |
96 | * of types in the definition of jack_property_t above. | |
97 | * If non-null, the caller must free this value with jack_free(). | |
98 | * | |
99 | * @return 0 on success, -1 if the @p subject has no @p key property. | |
100 | */ | |
101 | int | |
102 | jack_get_property(jack_uuid_t subject, | |
103 | const char* key, | |
104 | char** value, | |
105 | char** type); | |
106 | ||
107 | /** | |
108 | * A description of a subject (a set of properties). | |
109 | */ | |
110 | typedef struct { | |
111 | jack_uuid_t subject; /**< Subject being described. */ | |
112 | uint32_t property_cnt; /**< Number of elements in "properties". */ | |
113 | jack_property_t* properties; /**< Array of properties. */ | |
114 | uint32_t property_size; /**< Private, do not use. */ | |
115 | } jack_description_t; | |
116 | ||
117 | /** | |
118 | * Free a description. | |
119 | * | |
120 | * @param desc a jack_description_t whose associated memory will all be released | |
121 | * @param free_description_itself if non-zero, then @param desc will also be passed to free() | |
122 | */ | |
123 | void | |
124 | jack_free_description (jack_description_t* desc, int free_description_itself); | |
125 | ||
126 | /** | |
127 | * Get a description of @p subject. | |
128 | * @param subject The subject to get all properties of. | |
129 | * @param desc Set to the description of subject if found, or NULL otherwise. | |
130 | * The caller must free this value with jack_free_description(). | |
131 | * @return 0 on success, -1 if no @p subject with any properties exists. | |
132 | */ | |
133 | int | |
134 | jack_get_properties (jack_uuid_t subject, | |
135 | jack_description_t* desc); | |
136 | ||
137 | /** | |
138 | * Get descriptions for all subjects with metadata. | |
139 | * @param descs Set to a NULL-terminated array of descriptions. | |
140 | * The caller must free each of these with jack_free_description(), | |
141 | * and the array itself with jack_free(). | |
142 | * @return 0 on success. | |
143 | */ | |
144 | int | |
145 | jack_get_all_properties (jack_description_t** descs); | |
146 | ||
147 | /** | |
148 | * Remove a single property on a subject. | |
149 | * | |
150 | * @param client The JACK client making the request to remove the property. | |
151 | * @param subject The subject to remove the property from. | |
152 | * @param key The key of the property to be removed. | |
153 | * | |
154 | * @return 0 on success, -1 otherwise | |
155 | */ | |
156 | int jack_remove_property (jack_client_t* client, jack_uuid_t subject, const char* key); | |
157 | ||
158 | /** | |
159 | * Remove all properties on a subject. | |
160 | * | |
161 | * @param client The JACK client making the request to remove some properties. | |
162 | * @param subject The subject to remove all properties from. | |
163 | * | |
164 | * @return a count of the number of properties removed, or -1 on error. | |
165 | */ | |
166 | int jack_remove_properties (jack_client_t* client, jack_uuid_t subject); | |
167 | ||
168 | /** | |
169 | * Remove all properties. | |
170 | * | |
171 | * WARNING!! This deletes all metadata managed by a running JACK server. | |
172 | * Data lost cannot be recovered (though it can be recreated by new calls | |
173 | * to jack_set_property()). | |
174 | * | |
175 | * @param client The JACK client making the request to remove all properties | |
176 | * | |
177 | * @return 0 on success, -1 otherwise | |
178 | */ | |
179 | int jack_remove_all_properties (jack_client_t* client); | |
180 | ||
181 | typedef enum { | |
182 | PropertyCreated, | |
183 | PropertyChanged, | |
184 | PropertyDeleted | |
185 | } jack_property_change_t; | |
186 | ||
187 | typedef void (*JackPropertyChangeCallback)(jack_uuid_t subject, | |
188 | const char* key, | |
189 | jack_property_change_t change, | |
190 | void* arg); | |
191 | ||
192 | /** | |
193 | * Arrange for @p client to call @p callback whenever a property is created, | |
194 | * changed or deleted. | |
195 | * | |
196 | * @param client the JACK client making the request | |
197 | * @param callback the function to be invoked when a property change occurs | |
198 | * @param arg the argument to be passed to @param callback when it is invoked | |
199 | * | |
200 | * @return 0 success, -1 otherwise. | |
201 | */ | |
202 | int jack_set_property_change_callback (jack_client_t* client, | |
203 | JackPropertyChangeCallback callback, | |
204 | void* arg); | |
205 | ||
206 | #ifdef __cplusplus | |
207 | } /* namespace */ | |
208 | #endif | |
209 | ||
210 | /** | |
211 | * @} | |
212 | */ | |
213 | ||
214 | extern const char* JACK_METADATA_PRETTY_NAME; | |
215 | extern const char* JACK_METADATA_HARDWARE; | |
216 | extern const char* JACK_METADATA_CONNECTED; | |
217 | extern const char* JACK_METADATA_PORT_GROUP; | |
218 | extern const char* JACK_METADATA_ICON_SMALL; | |
219 | extern const char* JACK_METADATA_ICON_LARGE; | |
220 | ||
221 | #endif /* __jack_metadata_h__ */ |
241 | 241 | void jack_session_commands_free (jack_session_command_t *cmds) JACK_WEAK_EXPORT; |
242 | 242 | |
243 | 243 | /** |
244 | * Get the session ID for a client name. | |
245 | * | |
246 | * The session manager needs this to reassociate a client name to the session_id. | |
247 | * | |
248 | * The caller is responsible for calling jack_free(3) on any non-NULL | |
249 | * returned value. | |
250 | */ | |
251 | char *jack_get_uuid_for_client_name (jack_client_t *client, | |
252 | const char *client_name) JACK_WEAK_EXPORT; | |
253 | ||
254 | /** | |
255 | * Get the client name for a session_id. | |
256 | * | |
257 | * In order to snapshot the graph connections, the session manager needs to map | |
258 | * session_ids to client names. | |
259 | * | |
260 | * The caller is responsible for calling jack_free(3) on any non-NULL | |
261 | * returned value. | |
262 | */ | |
263 | char *jack_get_client_name_by_uuid (jack_client_t *client, | |
264 | const char *client_uuid ) JACK_WEAK_EXPORT; | |
265 | ||
266 | /** | |
267 | 244 | * Reserve a client name and associate it with a UUID. |
268 | 245 | * |
269 | 246 | * When a client later calls jack_client_open() and specifies the UUID, jackd |
21 | 21 | #define __jack_types_h__ |
22 | 22 | |
23 | 23 | #include <jack/systemdeps.h> |
24 | ||
25 | typedef uint64_t jack_uuid_t; | |
24 | 26 | |
25 | 27 | typedef int32_t jack_shmsize_t; |
26 | 28 |
0 | /* | |
1 | Copyright (C) 2013 Paul Davis | |
2 | ||
3 | This program is free software; you can redistribute it and/or modify | |
4 | it under the terms of the GNU Lesser General Public License as published by | |
5 | the Free Software Foundation; either version 2.1 of the License, or | |
6 | (at your option) any later version. | |
7 | ||
8 | This program is distributed in the hope that it will be useful, | |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | GNU Lesser General Public License for more details. | |
12 | ||
13 | You should have received a copy of the GNU Lesser General Public License | |
14 | along with this program; if not, write to the Free Software | |
15 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
16 | ||
17 | */ | |
18 | ||
19 | #ifndef __jack_uuid_h__ | |
20 | #define __jack_uuid_h__ | |
21 | ||
22 | #include <jack/types.h> | |
23 | ||
24 | #ifdef __cplusplus | |
25 | extern "C" { | |
26 | #endif | |
27 | ||
28 | #define JACK_UUID_SIZE 36 | |
29 | #define JACK_UUID_STRING_SIZE (JACK_UUID_SIZE+1) /* includes trailing null */ | |
30 | #define JACK_UUID_EMPTY_INITIALIZER 0 | |
31 | ||
32 | extern jack_uuid_t jack_client_uuid_generate (); | |
33 | extern jack_uuid_t jack_port_uuid_generate (uint32_t port_id); | |
34 | ||
35 | extern uint32_t jack_uuid_to_index (jack_uuid_t); | |
36 | ||
37 | extern int jack_uuid_compare (jack_uuid_t, jack_uuid_t); | |
38 | extern void jack_uuid_copy (jack_uuid_t* dst, jack_uuid_t src); | |
39 | extern void jack_uuid_clear (jack_uuid_t*); | |
40 | extern int jack_uuid_parse (const char *buf, jack_uuid_t*); | |
41 | extern void jack_uuid_unparse (jack_uuid_t, char buf[JACK_UUID_STRING_SIZE]); | |
42 | extern int jack_uuid_empty (jack_uuid_t); | |
43 | ||
44 | #ifdef __cplusplus | |
45 | } /* namespace */ | |
46 | #endif | |
47 | ||
48 | #endif /* __jack_uuid_h__ */ | |
49 |
444 | 444 | _mm_store_ss((float*)z+1, (__m128)shuffled1); |
445 | 445 | _mm_store_ss((float*)z+2, (__m128)shuffled2); |
446 | 446 | _mm_store_ss((float*)z+3, (__m128)shuffled3); |
447 | #endif | |
447 | 448 | |
448 | 449 | for (i = 0; i != 4; ++i) { |
449 | 450 | memcpy (dst, z+i, 3); |
450 | 451 | dst += dst_skip; |
451 | 452 | } |
452 | #endif | |
453 | 453 | |
454 | 454 | nsamples -= 4; |
455 | 455 | src += 4; |
88 | 88 | fprintf (stderr, "cannot connect input ports\n"); |
89 | 89 | } |
90 | 90 | |
91 | free (ports); | |
91 | jack_free (ports); | |
92 | 92 | |
93 | 93 | ports = jack_get_ports (client, NULL, NULL, |
94 | 94 | JackPortIsPhysical|JackPortIsInput); |
101 | 101 | fprintf (stderr, "cannot connect output ports\n"); |
102 | 102 | } |
103 | 103 | |
104 | free (ports); | |
104 | jack_free (ports); | |
105 | 105 | |
106 | 106 | return 0; /* success */ |
107 | 107 | } |
1185 | 1185 | } |
1186 | 1186 | } |
1187 | 1187 | |
1188 | outSize = sizeof(sub_device); | |
1188 | 1189 | err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); |
1189 | 1190 | vector<AudioDeviceID> playbackDeviceIDArray; |
1190 | 1191 | |
1464 | 1465 | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; |
1465 | 1466 | pluginAOPA.mElement = kAudioObjectPropertyElementMaster; |
1466 | 1467 | outDataSize = sizeof(CFStringRef); |
1467 | osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... | |
1468 | osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First capture is master... | |
1468 | 1469 | if (osErr != noErr) { |
1469 | 1470 | jack_error("JackCoreAudioAdapter::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); |
1470 | 1471 | printError(osErr); |
851 | 851 | |
852 | 852 | err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); |
853 | 853 | vector<AudioDeviceID> captureDeviceIDArray; |
854 | ||
855 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input device %d", captureDeviceID); | |
854 | 856 | |
855 | 857 | if (err != noErr) { |
856 | 858 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input device does not have subdevices"); |
857 | 859 | captureDeviceIDArray.push_back(captureDeviceID); |
858 | 860 | } else { |
859 | 861 | int num_devices = outSize / sizeof(AudioObjectID); |
860 | jack_log("JackCoreAudioDriver::CreateAggregateDevice :Input device has %d subdevices", num_devices); | |
862 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input device has %d subdevices", num_devices); | |
861 | 863 | for (int i = 0; i < num_devices; i++) { |
864 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input sub_device %d", sub_device[i]); | |
862 | 865 | captureDeviceIDArray.push_back(sub_device[i]); |
863 | 866 | } |
864 | 867 | } |
865 | 868 | |
869 | outSize = sizeof(sub_device); | |
866 | 870 | err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); |
867 | 871 | vector<AudioDeviceID> playbackDeviceIDArray; |
872 | ||
873 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output device %d", playbackDeviceID); | |
868 | 874 | |
869 | 875 | if (err != noErr) { |
870 | 876 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output device does not have subdevices"); |
873 | 879 | int num_devices = outSize / sizeof(AudioObjectID); |
874 | 880 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output device has %d subdevices", num_devices); |
875 | 881 | for (int i = 0; i < num_devices; i++) { |
882 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output sub_device %d", sub_device[i]); | |
876 | 883 | playbackDeviceIDArray.push_back(sub_device[i]); |
877 | 884 | } |
878 | 885 | } |
905 | 912 | |
906 | 913 | for (UInt32 i = 0; i < captureDeviceID.size(); i++) { |
907 | 914 | if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { |
908 | jack_error("CreateAggregateDevice : cannot set SR of input device"); | |
915 | jack_error("CreateAggregateDeviceAux : cannot set SR of input device"); | |
909 | 916 | } else { |
910 | 917 | // Check clock domain |
911 | 918 | osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); |
912 | 919 | if (osErr != 0) { |
913 | jack_error("CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | |
920 | jack_error("CreateAggregateDeviceAux : kAudioDevicePropertyClockDomain error"); | |
914 | 921 | printError(osErr); |
915 | 922 | } else { |
916 | 923 | keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; |
917 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); | |
924 | jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : input clockdomain = %d", clockdomain); | |
918 | 925 | if (clockdomain != 0 && clockdomain != keptclockdomain) { |
919 | jack_error("CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | |
926 | jack_error("CreateAggregateDeviceAux : devices do not share the same clock!! clock drift compensation would be needed..."); | |
920 | 927 | need_clock_drift_compensation = true; |
921 | 928 | } |
922 | 929 | } |
925 | 932 | |
926 | 933 | for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { |
927 | 934 | if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { |
928 | jack_error("CreateAggregateDevice : cannot set SR of output device"); | |
935 | jack_error("CreateAggregateDeviceAux : cannot set SR of output device"); | |
929 | 936 | } else { |
930 | 937 | // Check clock domain |
931 | 938 | osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); |
932 | 939 | if (osErr != 0) { |
933 | jack_error("CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); | |
940 | jack_error("CreateAggregateDeviceAux : kAudioDevicePropertyClockDomain error"); | |
934 | 941 | printError(osErr); |
935 | 942 | } else { |
936 | 943 | keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; |
937 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); | |
944 | jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : output clockdomain = %d", clockdomain); | |
938 | 945 | if (clockdomain != 0 && clockdomain != keptclockdomain) { |
939 | jack_error("CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); | |
946 | jack_error("CreateAggregateDeviceAux : devices do not share the same clock!! clock drift compensation would be needed..."); | |
940 | 947 | need_clock_drift_compensation = true; |
941 | 948 | } |
942 | 949 | } |
965 | 972 | |
966 | 973 | osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); |
967 | 974 | if (osErr != noErr) { |
968 | jack_error("CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | |
975 | jack_error("CreateAggregateDeviceAux : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); | |
969 | 976 | printError(osErr); |
970 | 977 | return osErr; |
971 | 978 | } |
981 | 988 | |
982 | 989 | osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); |
983 | 990 | if (osErr != noErr) { |
984 | jack_error("CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); | |
991 | jack_error("CreateAggregateDeviceAux : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); | |
985 | 992 | printError(osErr); |
986 | 993 | return osErr; |
987 | 994 | } |
1008 | 1015 | SInt32 system; |
1009 | 1016 | Gestalt(gestaltSystemVersion, &system); |
1010 | 1017 | |
1011 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); | |
1018 | jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : system version = %x limit = %x", system, 0x00001054); | |
1012 | 1019 | |
1013 | 1020 | // Starting with 10.5.4 systems, the AD can be internal... (better) |
1014 | 1021 | if (system < 0x00001054) { |
1015 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); | |
1022 | jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : public aggregate device...."); | |
1016 | 1023 | } else { |
1017 | jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); | |
1024 | jack_log("JackCoreAudioDriver::CreateAggregateDeviceAux : private aggregate device...."); | |
1018 | 1025 | CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); |
1019 | 1026 | } |
1020 | 1027 | |
1098 | 1105 | |
1099 | 1106 | osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); |
1100 | 1107 | if (osErr != noErr) { |
1101 | jack_error("CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); | |
1108 | jack_error("CreateAggregateDeviceAux : AudioObjectGetPropertyDataSize error"); | |
1102 | 1109 | printError(osErr); |
1103 | 1110 | goto error; |
1104 | 1111 | } |
1105 | 1112 | |
1106 | 1113 | osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); |
1107 | 1114 | if (osErr != noErr) { |
1108 | jack_error("CreateAggregateDevice : AudioObjectGetPropertyData error"); | |
1115 | jack_error("CreateAggregateDeviceAux : AudioObjectGetPropertyData error"); | |
1109 | 1116 | printError(osErr); |
1110 | 1117 | goto error; |
1111 | 1118 | } |
1124 | 1131 | outDataSize = sizeof(CFMutableArrayRef); |
1125 | 1132 | osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); |
1126 | 1133 | if (osErr != noErr) { |
1127 | jack_error("CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); | |
1134 | jack_error("CreateAggregateDeviceAux : AudioObjectSetPropertyData for sub-device list error"); | |
1128 | 1135 | printError(osErr); |
1129 | 1136 | goto error; |
1130 | 1137 | } |
1142 | 1149 | pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; |
1143 | 1150 | pluginAOPA.mElement = kAudioObjectPropertyElementMaster; |
1144 | 1151 | outDataSize = sizeof(CFStringRef); |
1145 | osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... | |
1152 | osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First capture is master... | |
1146 | 1153 | if (osErr != noErr) { |
1147 | jack_error("CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); | |
1154 | jack_error("CreateAggregateDeviceAux : AudioObjectSetPropertyData for master device error"); | |
1148 | 1155 | printError(osErr); |
1149 | 1156 | goto error; |
1150 | 1157 | } |
1162 | 1169 | // Get the property data size |
1163 | 1170 | osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); |
1164 | 1171 | if (osErr != noErr) { |
1165 | jack_error("CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | |
1172 | jack_error("CreateAggregateDeviceAux kAudioObjectPropertyOwnedObjects error"); | |
1166 | 1173 | printError(osErr); |
1167 | 1174 | } |
1168 | 1175 | |
1169 | 1176 | // Calculate the number of object IDs |
1170 | 1177 | subDevicesNum = outSize / sizeof(AudioObjectID); |
1171 | jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); | |
1178 | jack_info("JackCoreAudioDriver::CreateAggregateDeviceAux clock drift compensation, number of sub-devices = %d", subDevicesNum); | |
1172 | 1179 | AudioObjectID subDevices[subDevicesNum]; |
1173 | 1180 | outSize = sizeof(subDevices); |
1174 | 1181 | |
1175 | 1182 | osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); |
1176 | 1183 | if (osErr != noErr) { |
1177 | jack_error("CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); | |
1184 | jack_error("CreateAggregateDeviceAux kAudioObjectPropertyOwnedObjects error"); | |
1178 | 1185 | printError(osErr); |
1179 | 1186 | } |
1180 | 1187 | |
1183 | 1190 | UInt32 theDriftCompensationValue = 1; |
1184 | 1191 | osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); |
1185 | 1192 | if (osErr != noErr) { |
1186 | jack_error("CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); | |
1193 | jack_error("CreateAggregateDeviceAux kAudioSubDevicePropertyDriftCompensation error"); | |
1187 | 1194 | printError(osErr); |
1188 | 1195 | } |
1189 | 1196 | } |
1414 | 1421 | int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchannels, int& outchannels, int& in_maxChannels, int& out_maxChannels, bool strict) |
1415 | 1422 | { |
1416 | 1423 | OSStatus err = noErr; |
1424 | ||
1425 | jack_log("JackCoreAudioDriver::SetupChannels : fDeviceID = %d", fDeviceID); | |
1417 | 1426 | |
1418 | 1427 | if (capturing) { |
1419 | 1428 | err = GetTotalChannels(fDeviceID, in_maxChannels, true); |
1470 | 1479 | OSStatus err = noErr; |
1471 | 1480 | UInt32 tmp_buffer_size = buffer_size; |
1472 | 1481 | UInt32 outSize = sizeof(UInt32); |
1473 | ||
1482 | ||
1474 | 1483 | err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyBufferFrameSize, &outSize, &tmp_buffer_size); |
1475 | 1484 | if (err != noErr) { |
1476 | 1485 | jack_error("Cannot get buffer size %ld", buffer_size); |
1693 | 1702 | |
1694 | 1703 | err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); |
1695 | 1704 | if (err1 != noErr) { |
1696 | jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); | |
1705 | jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output"); | |
1697 | 1706 | printError(err1); |
1698 | 1707 | goto error; |
1699 | 1708 | } |
444 | 444 | #endif |
445 | 445 | int res; |
446 | 446 | if ((res = recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fSendAddr), &addr_len)) < 0) { |
447 | jack_error("CatchHost fd = %ld err = %s", fSockfd, strerror(errno)); | |
447 | jack_log("CatchHost fd = %ld err = %s", fSockfd, strerror(errno)); | |
448 | 448 | } |
449 | 449 | return res; |
450 | 450 | } |
0 | 0 | #! /usr/bin/env python |
1 | 1 | # encoding: utf-8 |
2 | 2 | |
3 | import Build | |
4 | import re | |
5 | import os | |
6 | ||
7 | 3 | def configure(conf): |
8 | conf.check_cc(function_name='Pa_GetVersion', header_name='portaudio.h', lib='portaudio', uselib_store="PORTAUDIO", define_name='HAVE_PORTAUDIO') | |
4 | conf.check_cfg(package='portaudio-2.0', uselib_store='PORTAUDIO', atleast_version='19', args='--cflags --libs') | |
9 | 5 | conf.env['BUILD_DRIVER_PORTAUDIO'] = conf.is_defined('HAVE_PORTAUDIO') |
10 | 6 | |
7 | def create_jack_driver_obj(bld, target, sources, uselib = None): | |
8 | driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) | |
9 | driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' | |
10 | driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] | |
11 | driver.includes = ['.', '..' , '../windows', '../common', '../common/jack'] | |
12 | driver.target = target | |
13 | driver.source = sources | |
14 | driver.install_path = '${ADDON_DIR}/' | |
15 | driver.use = ['serverlib'] | |
16 | if uselib: | |
17 | driver.use += uselib | |
18 | return driver | |
19 | ||
11 | 20 | def build(bld): |
12 | print "" | |
21 | if bld.env['BUILD_JACKD'] == True: | |
22 | jackd = bld(features = ['cxx', 'cxxprogram']) | |
23 | jackd.includes = ['..', '../windows', '../common/jack', '../common', '../dbus'] | |
24 | jackd.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] | |
25 | jackd.source = ['../common/Jackdmp.cpp'] | |
26 | jackd.install_path = '${BINDIR}' | |
27 | jackd.use = ['serverlib'] | |
28 | jackd.target = 'jackd' | |
13 | 29 | |
30 | create_jack_driver_obj(bld, 'dummy', '../common/JackDummyDriver.cpp') | |
31 | ||
32 | winmme_driver_src = [ | |
33 | 'winmme/JackWinMMEDriver.cpp', | |
34 | 'winmme/JackWinMMEInputPort.cpp', | |
35 | 'winmme/JackWinMMEOutputPort.cpp', | |
36 | 'winmme/JackWinMMEPort.cpp', | |
37 | ] | |
38 | ||
39 | if bld.env['BUILD_DRIVER_WINMME'] == True: | |
40 | winmme_driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) | |
41 | winmme_driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' | |
42 | winmme_driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] | |
43 | winmme_driver.includes = ['.', '..' , '../windows', '../common', '../common/jack'] | |
44 | winmme_driver.target = 'winmme' | |
45 | winmme_driver.source = winmme_driver_src | |
46 | winmme_driver.install_path = '${ADDON_DIR}/' | |
47 | winmme_driver.use = ['serverlib', 'WINMME'] | |
48 | ||
49 | portaudio_driver_src = [ | |
50 | 'portaudio/JackPortAudioDevices.cpp', | |
51 | 'portaudio/JackPortAudioDriver.cpp', | |
52 | ] | |
53 | ||
54 | if bld.env['BUILD_DRIVER_PORTAUDIO'] == True: | |
55 | portaudio_driver = bld(features = ['c', 'cxx', 'cxxshlib', 'cshlib']) | |
56 | portaudio_driver.env['cxxshlib_PATTERN'] = 'jack_%s.dll' | |
57 | portaudio_driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] | |
58 | portaudio_driver.includes = ['.', '..' , '../windows', '../common', '../common/jack'] | |
59 | portaudio_driver.target = 'portaudio' | |
60 | portaudio_driver.source = portaudio_driver_src | |
61 | portaudio_driver.install_path = '${ADDON_DIR}/' | |
62 | portaudio_driver.use = ['serverlib', 'PORTAUDIO' ] | |
63 | ||
64 | create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') | |
65 | ||
66 | create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') | |
67 | ||
68 | create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', | |
69 | '../common/netjack.c', | |
70 | '../common/netjack_packet.c' ], ["SAMPLERATE", "CELT"] ) |