@ciphore/radiocli 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +103 -2
- package/CONTRIBUTING.md +28 -0
- package/README.md +108 -253
- package/SECURITY.md +23 -1
- package/dist/agent/alarm-service.js +10 -7
- package/dist/agent/cli.js +16 -1
- package/dist/agent/command-schema.js +47 -0
- package/dist/agent/headless-host.js +226 -81
- package/dist/agent/launcher.js +2 -1
- package/dist/agent/mcp-server.js +10 -5
- package/dist/agent/service.js +75 -40
- package/dist/agent/session.js +214 -24
- package/dist/agent/tui-session.js +213 -0
- package/dist/alarms/cli.js +19 -3
- package/dist/alarms/occurrence-cache.js +25 -0
- package/dist/alarms/runner.js +87 -23
- package/dist/alarms/schedule.js +29 -1
- package/dist/alarms/scheduler.js +11 -3
- package/dist/alarms/system-volume-linux.js +160 -0
- package/dist/alarms/system-volume-ownership.js +76 -8
- package/dist/alarms/system-volume.js +44 -23
- package/dist/cli/arguments.js +212 -0
- package/dist/cli/completion.js +44 -0
- package/dist/cli/doctor.js +156 -0
- package/dist/cli/interactive.js +79 -0
- package/dist/cli/listener.js +227 -0
- package/dist/cli/output.js +121 -0
- package/dist/cli/render-tui.js +34 -0
- package/dist/cli.js +182 -199
- package/dist/platform/capabilities.js +8 -1
- package/dist/platform/desktop-media.js +61 -0
- package/dist/platform/diagnostics.js +273 -0
- package/dist/platform/json-worker.js +111 -0
- package/dist/platform/launch-command.js +9 -6
- package/dist/platform/mpris.js +356 -0
- package/dist/platform/network.js +69 -1
- package/dist/platform/omarchy.js +147 -0
- package/dist/platform/packages.js +7 -1
- package/dist/platform/runtime.js +1 -1
- package/dist/platform/terminals.js +24 -4
- package/dist/player/airplay-discovery.js +144 -61
- package/dist/player/airplay-policy.js +15 -0
- package/dist/player/airplay-process.js +63 -0
- package/dist/player/airplay-readiness.js +42 -0
- package/dist/player/airplay-sender-health.js +49 -49
- package/dist/player/airplay-sender-package.js +5 -0
- package/dist/player/airplay-sender-patch.js +102 -4
- package/dist/player/airplay-setup.js +51 -0
- package/dist/player/airplay-worker.js +97 -41
- package/dist/player/backend-install.js +9 -6
- package/dist/player/ffmpeg-input.js +37 -0
- package/dist/player/mpv-desktop-media.js +194 -0
- package/dist/player/mpv-ipc-client.js +51 -2
- package/dist/player/player-controller.js +390 -73
- package/dist/player/radio-engine.js +282 -0
- package/dist/playlists/playlist.js +18 -16
- package/dist/providers/cache.js +291 -75
- package/dist/providers/discovery-session.js +111 -0
- package/dist/providers/provider-manager.js +106 -28
- package/dist/providers/radio-browser.js +272 -41
- package/dist/providers/radio-garden.js +4 -2
- package/dist/setup-playback.js +152 -0
- package/dist/setup.js +88 -21
- package/dist/storage/file-lock.js +130 -0
- package/dist/storage/read-settings.js +33 -0
- package/dist/storage/replace-file.js +20 -0
- package/dist/storage/repository.js +247 -0
- package/dist/storage/station-identity.js +21 -0
- package/dist/storage/station-schema.js +27 -0
- package/dist/storage/store.js +314 -76
- package/dist/types.js +22 -1
- package/dist/ui/AdaptiveContent.js +21 -24
- package/dist/ui/App.js +708 -454
- package/dist/ui/AppContent.js +5 -5
- package/dist/ui/airplay-settings.js +12 -5
- package/dist/ui/bidi-ranges.js +45 -0
- package/dist/ui/components/AdaptiveMarquee.js +16 -9
- package/dist/ui/components/ReceiverVisualRow.js +39 -0
- package/dist/ui/format.js +37 -4
- package/dist/ui/help-content.js +5 -2
- package/dist/ui/rtl-output.js +137 -0
- package/dist/ui/screen-items.js +10 -4
- package/dist/ui/screens/AirPlaySettingsScreen.js +3 -3
- package/dist/ui/screens/AlarmsScreen.js +5 -2
- package/dist/ui/screens/HelpScreen.js +3 -3
- package/dist/ui/screens/NowPlayingScreen.js +2 -21
- package/dist/ui/screens/SettingsScreen.js +16 -16
- package/dist/ui/screens/StatsScreen.js +1 -1
- package/dist/ui/text-direction.js +9 -0
- package/dist/ui/theme.js +46 -0
- package/dist/ui/use-alarm-tui.js +24 -24
- package/dist/ui/use-app-input.js +42 -8
- package/dist/ui/use-command-executor.js +21 -14
- package/dist/ui/visualizers/boat-lake-kernel.js +325 -0
- package/dist/ui/visualizers/boat-lake.js +161 -0
- package/dist/ui/visualizers/gallop.js +2 -2
- package/dist/ui/visualizers/receiver-style-registry.js +3 -1
- package/dist/ui/visualizers/receiver-visualizers.js +6 -108
- package/dist/ui/visualizers/sumi-ocean.js +183 -0
- package/dist/ui/visualizers/terminal-cell.js +45 -0
- package/dist/update-check.js +2 -1
- package/docs/THIRD_PARTY_NOTICES.md +6 -4
- package/docs/boat-lake.md +88 -0
- package/docs/sumi-ocean.md +80 -0
- package/package.json +36 -12
- package/scripts/build-airplay-native.mjs +22 -0
- package/vendor/node-airtunes2/LICENSE +208 -0
- package/vendor/node-airtunes2/RADIOCLI_PATCH.md +29 -0
- package/vendor/node-airtunes2/README.md +225 -0
- package/vendor/node-airtunes2/UPSTREAM.json +50 -0
- package/vendor/node-airtunes2/binding.gyp +41 -0
- package/vendor/node-airtunes2/lib/ap2_test.js +4 -0
- package/vendor/node-airtunes2/lib/atv.js +307 -0
- package/vendor/node-airtunes2/lib/atvAuthenticator.js +136 -0
- package/vendor/node-airtunes2/lib/audio_out.js +69 -0
- package/vendor/node-airtunes2/lib/circular_buffer.js +133 -0
- package/vendor/node-airtunes2/lib/config.js +26 -0
- package/vendor/node-airtunes2/lib/device_airtunes.js +532 -0
- package/vendor/node-airtunes2/lib/devices.js +266 -0
- package/vendor/node-airtunes2/lib/ed25519.js +26 -0
- package/vendor/node-airtunes2/lib/homekit/credentials.js +86 -0
- package/vendor/node-airtunes2/lib/homekit/encryption.js +69 -0
- package/vendor/node-airtunes2/lib/homekit/number.js +44 -0
- package/vendor/node-airtunes2/lib/homekit/tlv.js +95 -0
- package/vendor/node-airtunes2/lib/http.js +189 -0
- package/vendor/node-airtunes2/lib/index.d.ts +141 -0
- package/vendor/node-airtunes2/lib/index.js +127 -0
- package/vendor/node-airtunes2/lib/ntp.js +37 -0
- package/vendor/node-airtunes2/lib/num_util.js +21 -0
- package/vendor/node-airtunes2/lib/packet_pool.js +43 -0
- package/vendor/node-airtunes2/lib/rtsp.js +1807 -0
- package/vendor/node-airtunes2/lib/srp.js +158 -0
- package/vendor/node-airtunes2/lib/udp_servers.js +214 -0
- package/vendor/node-airtunes2/lib/util.js +12 -0
- package/vendor/node-airtunes2/package.json +31 -0
- package/vendor/node-airtunes2/src/CADebugMacros.h +257 -0
- package/vendor/node-airtunes2/src/CAHostTimeBase.cpp +105 -0
- package/vendor/node-airtunes2/src/CAHostTimeBase.h +224 -0
- package/vendor/node-airtunes2/src/aes_utils.c +864 -0
- package/vendor/node-airtunes2/src/aes_utils.h +24 -0
- package/vendor/node-airtunes2/src/base64.c +136 -0
- package/vendor/node-airtunes2/src/base64.h +42 -0
- package/vendor/node-airtunes2/src/bindings.cc +29 -0
- package/vendor/node-airtunes2/src/codec.cc +170 -0
- package/vendor/node-airtunes2/src/coreaudio.cc +332 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
// Conversion to modern node (v4)
|
|
2
|
+
//
|
|
3
|
+
// TODO: understand. I have no idea what I'm doing here. HandleScope/Isolate?
|
|
4
|
+
//
|
|
5
|
+
// https://nodejs.org/api/addons.html
|
|
6
|
+
// https://developers.google.com/v8/embed?hl=en
|
|
7
|
+
// https://strongloop.com/strongblog/node-js-v0-12-c-apis-breaking/
|
|
8
|
+
// https://github.com/nodejs/nan/blob/master/doc/persistent.md
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
#include <node.h>
|
|
12
|
+
#include <node_buffer.h>
|
|
13
|
+
#include <v8.h>
|
|
14
|
+
//Includes from phoenixLib iOS HAL
|
|
15
|
+
#include <stdio.h>
|
|
16
|
+
#include <time.h>
|
|
17
|
+
#include <stdlib.h>
|
|
18
|
+
#include <unistd.h>
|
|
19
|
+
#include <stdarg.h>
|
|
20
|
+
#include <AudioToolbox/AudioToolbox.h>
|
|
21
|
+
#include <CoreFoundation/CoreFoundation.h>
|
|
22
|
+
#include "CAHostTimeBase.h"
|
|
23
|
+
#include <pthread.h>
|
|
24
|
+
#include <sys/resource.h>
|
|
25
|
+
|
|
26
|
+
#define FRAME_SIZE 1408
|
|
27
|
+
#define NUMBER_OF_BUFFERS 100
|
|
28
|
+
#define BUFFER_SIZE FRAME_SIZE * 4
|
|
29
|
+
|
|
30
|
+
using namespace v8;
|
|
31
|
+
using namespace node;
|
|
32
|
+
|
|
33
|
+
namespace nodeairtunes {
|
|
34
|
+
|
|
35
|
+
struct coreAudioObjects {
|
|
36
|
+
AudioQueueRef audioQueue;
|
|
37
|
+
|
|
38
|
+
unsigned int fillBufferIndex; // the index of the audioQueueBuffer that is being filled
|
|
39
|
+
|
|
40
|
+
size_t bytesFilled; // how many bytes have been filled
|
|
41
|
+
|
|
42
|
+
AudioQueueBufferRef audioQueueBuffer[NUMBER_OF_BUFFERS]; // audio queue buffers
|
|
43
|
+
bool inuse[NUMBER_OF_BUFFERS]; // flags to indicate that a buffer is still in use
|
|
44
|
+
|
|
45
|
+
bool isPlaying;
|
|
46
|
+
unsigned int buffersUsed;
|
|
47
|
+
|
|
48
|
+
OSStatus err;
|
|
49
|
+
|
|
50
|
+
pthread_mutex_t queueBuffersMutex; // a mutex to protect the inuse flags
|
|
51
|
+
pthread_cond_t queueBufferReadyCondition; // a condition varable for handling the inuse flags
|
|
52
|
+
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// This will free the AudioQueue when the wraping JS object is released by the GC
|
|
56
|
+
void coreAudio_weak_callback(const v8::WeakCallbackInfo<coreAudioObjects> &data) {
|
|
57
|
+
struct coreAudioObjects *coreAudio = (struct coreAudioObjects *) data.GetParameter();
|
|
58
|
+
AudioQueueDispose(coreAudio->audioQueue, true);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void OnAudioQueueBufferConsumed(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
|
|
62
|
+
struct coreAudioObjects* coreAudio;
|
|
63
|
+
coreAudio = (struct coreAudioObjects*) inUserData;
|
|
64
|
+
|
|
65
|
+
int bufIndex = -1;
|
|
66
|
+
for (unsigned int i = 0; i < NUMBER_OF_BUFFERS; i++) {
|
|
67
|
+
if (inBuffer == coreAudio->audioQueueBuffer[i]) {
|
|
68
|
+
bufIndex = i;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (bufIndex == -1) {
|
|
74
|
+
pthread_mutex_lock(&(coreAudio->queueBuffersMutex));
|
|
75
|
+
pthread_cond_signal(&(coreAudio->queueBufferReadyCondition));
|
|
76
|
+
pthread_mutex_unlock(&(coreAudio->queueBuffersMutex));
|
|
77
|
+
//DEBUG_AUDIOMANAGER_ERROR("Buffer mismatch !");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// signal waiting thread that the buffer is free.
|
|
81
|
+
pthread_mutex_lock(&(coreAudio->queueBuffersMutex));
|
|
82
|
+
coreAudio->inuse[bufIndex] = false;
|
|
83
|
+
coreAudio->buffersUsed--;
|
|
84
|
+
pthread_cond_signal(&(coreAudio->queueBufferReadyCondition));
|
|
85
|
+
pthread_mutex_unlock(&(coreAudio->queueBuffersMutex));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static void enqueueBuffer(struct coreAudioObjects *coreAudio) {
|
|
89
|
+
|
|
90
|
+
OSStatus err = 0;
|
|
91
|
+
|
|
92
|
+
// enqueue buffer
|
|
93
|
+
pthread_mutex_lock(&(coreAudio->queueBuffersMutex));
|
|
94
|
+
|
|
95
|
+
AudioQueueBufferRef fillBuf = coreAudio->audioQueueBuffer[coreAudio->fillBufferIndex];
|
|
96
|
+
fillBuf->mAudioDataByteSize = coreAudio->bytesFilled;
|
|
97
|
+
err = AudioQueueEnqueueBuffer(coreAudio->audioQueue, fillBuf, 0, NULL);
|
|
98
|
+
if (err) {
|
|
99
|
+
//DEBUG_AUDIOMANAGER_ERROR("enqueue failed !!!!! %d", coreAudio->fillBufferIndex);
|
|
100
|
+
coreAudio->bytesFilled = 0;
|
|
101
|
+
pthread_mutex_unlock(&(coreAudio->queueBuffersMutex));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
coreAudio->inuse[coreAudio->fillBufferIndex] = true; // set in use flag
|
|
106
|
+
coreAudio->buffersUsed++;
|
|
107
|
+
|
|
108
|
+
// go to next buffer
|
|
109
|
+
if (++(coreAudio->fillBufferIndex) >= NUMBER_OF_BUFFERS) coreAudio->fillBufferIndex = 0;
|
|
110
|
+
|
|
111
|
+
coreAudio->bytesFilled = 0; // reset bytes filled
|
|
112
|
+
|
|
113
|
+
// wait until next buffer is not in use
|
|
114
|
+
while (coreAudio->inuse[coreAudio->fillBufferIndex]) {
|
|
115
|
+
pthread_cond_wait(&(coreAudio->queueBufferReadyCondition), &(coreAudio->queueBuffersMutex));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
pthread_mutex_unlock(&(coreAudio->queueBuffersMutex));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
void NewCoreAudio(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
122
|
+
v8::Isolate* isolate = args.GetIsolate();
|
|
123
|
+
|
|
124
|
+
v8::HandleScope handle_scope(isolate);
|
|
125
|
+
|
|
126
|
+
struct coreAudioObjects *coreAudio
|
|
127
|
+
= (struct coreAudioObjects *) malloc(sizeof (*coreAudio));
|
|
128
|
+
|
|
129
|
+
v8::Persistent<v8::Object> o;
|
|
130
|
+
o.SetWeak(
|
|
131
|
+
coreAudio,
|
|
132
|
+
coreAudio_weak_callback,
|
|
133
|
+
v8::WeakCallbackType::kParameter
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
coreAudio->isPlaying = false;
|
|
137
|
+
coreAudio->buffersUsed = 0;
|
|
138
|
+
coreAudio->bytesFilled = 0;
|
|
139
|
+
coreAudio->fillBufferIndex = 0;
|
|
140
|
+
// initialize a mutex and condition so that we can block on buffers in use.
|
|
141
|
+
pthread_mutex_init(&(coreAudio->queueBuffersMutex), NULL);
|
|
142
|
+
pthread_cond_init(&(coreAudio->queueBufferReadyCondition), NULL);
|
|
143
|
+
|
|
144
|
+
AudioStreamBasicDescription LFormat;
|
|
145
|
+
OSStatus LRet;
|
|
146
|
+
|
|
147
|
+
LFormat.mSampleRate = 44100;
|
|
148
|
+
LFormat.mFormatID = kAudioFormatLinearPCM;
|
|
149
|
+
LFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger; // signed int
|
|
150
|
+
LFormat.mFramesPerPacket = 1; // for uncompressed audio
|
|
151
|
+
LFormat.mBytesPerFrame = 4; //AChannels * 2; // interleaved pcm datas (16bits per chan)
|
|
152
|
+
LFormat.mBytesPerPacket = 4; // for pcm: a packet contains a single frame
|
|
153
|
+
LFormat.mChannelsPerFrame = 2;
|
|
154
|
+
LFormat.mBitsPerChannel = 16;
|
|
155
|
+
|
|
156
|
+
// Allocating AudioQueue
|
|
157
|
+
|
|
158
|
+
if ((LRet = AudioQueueNewOutput(&LFormat, OnAudioQueueBufferConsumed, coreAudio, NULL, NULL, 0, &(coreAudio->audioQueue)))) {
|
|
159
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
OSStatus status = 0;
|
|
164
|
+
|
|
165
|
+
// Allocate buffers for the AudioQueue
|
|
166
|
+
for (int i = 0; i < NUMBER_OF_BUFFERS; ++i) {
|
|
167
|
+
status = AudioQueueAllocateBuffer(coreAudio->audioQueue, BUFFER_SIZE, &(coreAudio->audioQueueBuffer[i]));
|
|
168
|
+
coreAudio->inuse[i] = false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
args.GetReturnValue().Set(o.Get(isolate));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
void EnqueuePacket(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
175
|
+
v8::Isolate* isolate = args.GetIsolate();
|
|
176
|
+
Local<Context> ctx = isolate->GetCurrentContext();
|
|
177
|
+
|
|
178
|
+
if (args.Length() < 3) {
|
|
179
|
+
printf("expected: EnqueuePacket(coreAudio, pcmData, pcmSize)\n");
|
|
180
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
v8::Local<v8::Object> wrapper;
|
|
185
|
+
args[0]->ToObject(ctx).ToLocal(&wrapper);
|
|
186
|
+
struct coreAudioObjects *coreAudio = (struct coreAudioObjects *) *wrapper;
|
|
187
|
+
|
|
188
|
+
v8::Local<v8::Value> pcmBuffer = args[1];
|
|
189
|
+
Local<Object> pcmObject;
|
|
190
|
+
pcmBuffer->ToObject(ctx).ToLocal(&pcmObject);
|
|
191
|
+
unsigned char* pcmData = (unsigned char*) (Buffer::Data(pcmObject));
|
|
192
|
+
|
|
193
|
+
int32_t pcmSize = args[2]->Int32Value(ctx).FromJust();
|
|
194
|
+
|
|
195
|
+
//We have all infos needed
|
|
196
|
+
|
|
197
|
+
size_t offset = 0;
|
|
198
|
+
while (pcmSize) {
|
|
199
|
+
// if the space remaining in the buffer is not enough for this packet, then enqueue the buffer.
|
|
200
|
+
size_t bufSpaceRemaining = BUFFER_SIZE - coreAudio->bytesFilled;
|
|
201
|
+
if (bufSpaceRemaining < pcmSize) {
|
|
202
|
+
//DEBUG_AUDIOMANAGER_VERBOSE("Before enqueue");
|
|
203
|
+
enqueueBuffer(coreAudio);
|
|
204
|
+
//DEBUG_AUDIOMANAGER_VERBOSE("After enqueue");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
bufSpaceRemaining = BUFFER_SIZE - coreAudio->bytesFilled;
|
|
208
|
+
size_t copySize;
|
|
209
|
+
if (bufSpaceRemaining < pcmSize) {
|
|
210
|
+
copySize = bufSpaceRemaining;
|
|
211
|
+
} else {
|
|
212
|
+
copySize = pcmSize;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// copy data to the audio queue buffer
|
|
216
|
+
AudioQueueBufferRef fillBuf = coreAudio->audioQueueBuffer[coreAudio->fillBufferIndex];
|
|
217
|
+
memcpy((char*) fillBuf->mAudioData + coreAudio->bytesFilled, (const char*) (pcmData + offset), copySize);
|
|
218
|
+
|
|
219
|
+
// keep track of bytes filled and packets filled
|
|
220
|
+
coreAudio->bytesFilled += copySize;
|
|
221
|
+
|
|
222
|
+
pcmSize -= copySize;
|
|
223
|
+
offset += copySize;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
void Play(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
230
|
+
v8::Isolate* isolate = args.GetIsolate();
|
|
231
|
+
Local<Context> ctx = isolate->GetCurrentContext();
|
|
232
|
+
|
|
233
|
+
if (args.Length() < 2) {
|
|
234
|
+
printf("expected: Play(coreAudio, audioQueueTimeRef)\n");
|
|
235
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
v8::Local<v8::Object> wrapper;
|
|
240
|
+
args[0]->ToObject(ctx).ToLocal(&wrapper);
|
|
241
|
+
struct coreAudioObjects *coreAudio = (struct coreAudioObjects *) *wrapper;
|
|
242
|
+
|
|
243
|
+
int64_t timeStamp = args[1]->IntegerValue(ctx).FromJust();
|
|
244
|
+
|
|
245
|
+
AudioTimeStamp myAudioQueueStartTime; // = {0};
|
|
246
|
+
Float64 theNumberOfSecondsInTheFuture = timeStamp/44100.0;
|
|
247
|
+
|
|
248
|
+
Float64 hostTimeFreq = CAHostTimeBase::GetFrequency();
|
|
249
|
+
UInt64 startHostTime = CAHostTimeBase::GetCurrentTime() + theNumberOfSecondsInTheFuture * hostTimeFreq;
|
|
250
|
+
|
|
251
|
+
myAudioQueueStartTime.mFlags = kAudioTimeStampHostTimeValid;
|
|
252
|
+
myAudioQueueStartTime.mHostTime = startHostTime;
|
|
253
|
+
|
|
254
|
+
if (coreAudio->isPlaying == false) {
|
|
255
|
+
if (AudioQueueStart(coreAudio->audioQueue, &myAudioQueueStartTime)) {
|
|
256
|
+
printf("AudioQueueStart() Failed!\n");
|
|
257
|
+
} else {
|
|
258
|
+
coreAudio->isPlaying = true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
void Stop(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
266
|
+
v8::Isolate* isolate = args.GetIsolate();
|
|
267
|
+
Local<Context> ctx = isolate->GetCurrentContext();
|
|
268
|
+
|
|
269
|
+
if (args.Length() < 1) {
|
|
270
|
+
printf("expected: Play(coreAudio)\n");
|
|
271
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
v8::Local<v8::Object> wrapper;
|
|
276
|
+
args[0]->ToObject(ctx).ToLocal(&wrapper);
|
|
277
|
+
struct coreAudioObjects *coreAudio = (struct coreAudioObjects *) *wrapper;
|
|
278
|
+
|
|
279
|
+
if (coreAudio->isPlaying) {
|
|
280
|
+
if (AudioQueueStop(coreAudio->audioQueue, true)) {
|
|
281
|
+
printf("AudioQueueStop() Failed!\n");
|
|
282
|
+
} else {
|
|
283
|
+
coreAudio->isPlaying = false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
void SetVolume(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
291
|
+
v8::Isolate* isolate = args.GetIsolate();
|
|
292
|
+
Local<Context> ctx = isolate->GetCurrentContext();
|
|
293
|
+
|
|
294
|
+
if (args.Length() < 1) {
|
|
295
|
+
printf("expected: Play(coreAudio)\n");
|
|
296
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
v8::Local<v8::Object> wrapper;
|
|
301
|
+
args[0]->ToObject(ctx).ToLocal(&wrapper);
|
|
302
|
+
struct coreAudioObjects *coreAudio = (struct coreAudioObjects *) *wrapper;
|
|
303
|
+
float volumeToSet=args[1]->IntegerValue(ctx).FromJust()/100.0;
|
|
304
|
+
|
|
305
|
+
if (coreAudio->isPlaying)
|
|
306
|
+
AudioQueueSetParameter(coreAudio->audioQueue, kAudioQueueParam_Volume, volumeToSet);
|
|
307
|
+
|
|
308
|
+
args.GetReturnValue().Set(v8::Null(isolate));
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
void GetBufferLevel(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
312
|
+
v8::Isolate* isolate = args.GetIsolate();
|
|
313
|
+
Local<Context> ctx = isolate->GetCurrentContext();
|
|
314
|
+
|
|
315
|
+
v8::Local<v8::Object> wrapper;
|
|
316
|
+
args[0]->ToObject(ctx).ToLocal(&wrapper);
|
|
317
|
+
struct coreAudioObjects *coreAudio = (struct coreAudioObjects *) *wrapper;
|
|
318
|
+
v8::Local<v8::Integer> o = v8::Integer::New(isolate, (int)((coreAudio->buffersUsed/(float)NUMBER_OF_BUFFERS)*100));
|
|
319
|
+
|
|
320
|
+
args.GetReturnValue().Set(o);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
void InitCoreAudio(v8::Local<v8::Object> target) {
|
|
324
|
+
NODE_SET_METHOD(target, "enqueuePacket", EnqueuePacket);
|
|
325
|
+
NODE_SET_METHOD(target, "newCoreAudio", NewCoreAudio);
|
|
326
|
+
NODE_SET_METHOD(target, "play", Play);
|
|
327
|
+
NODE_SET_METHOD(target, "stop", Stop);
|
|
328
|
+
NODE_SET_METHOD(target, "setVolume", SetVolume);
|
|
329
|
+
NODE_SET_METHOD(target, "getBufferLevel", GetBufferLevel);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
}
|