Codebase list squeezelite / c0aef15
1.0rc2 - fix a missing mutex unlock in vorbis decde which could lead to lockup - alter pthread stacksize setting to be independant of min stack size - attempt to minimise pagefaults further by touching memory buffers at startup - mac: use paMacCorePlayNice rather than Pro mode for local interface (mark.ruys) Adrian Smith 11 years ago
7 changed file(s) with 69 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
116116 #if LINUX || OSX
117117 pthread_attr_t attr;
118118 pthread_attr_init(&attr);
119 pthread_attr_setstacksize(&attr, DECODE_THREAD_STACK_SIZE);
119 pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + DECODE_THREAD_STACK_SIZE);
120120 pthread_create(&thread, &attr, decode_thread, NULL);
121121 pthread_attr_destroy(&attr);
122122 #endif
267267 winsock_init();
268268 #endif
269269
270 stream_init(log_stream, stream_buf_size);
271
270272 #if ALSA
271273 output_init(log_output, output_device, output_buf_size, alsa_buffer_time, alsa_period_count, alsa_sample_fmt, alsa_mmap,
272274 max_rate, rt_priority);
274276 #if PORTAUDIO
275277 output_init(log_output, output_device, output_buf_size, pa_latency, max_rate);
276278 #endif
277 stream_init(log_stream, stream_buf_size);
279
278280 decode_init(log_decode, codecs);
279281
280282 slimproto(log_slimproto, server ? server_addr(server) : 0, mac, name);
2525 #if ALSA
2626 #include <alsa/asoundlib.h>
2727 #include <sys/mman.h>
28 #include <malloc.h>
2829 #endif
2930 #if PORTAUDIO
3031 #include <portaudio.h>
4142 #if ALSA
4243
4344 #define MAX_SILENCE_FRAMES 1024
45 #define MAX_DEVICE_LEN 128
4446
4547 static snd_pcm_format_t fmts[] = { SND_PCM_FORMAT_S32_LE, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S16_LE,
4648 SND_PCM_FORMAT_UNKNOWN };
5254
5355 // ouput device
5456 static struct {
55 char *device;
57 char device[MAX_DEVICE_LEN + 1];
5658 snd_pcm_format_t format;
5759 snd_pcm_uframes_t period_size;
5860 unsigned rate;
198200 if (*pcmp) alsa_close(*pcmp);
199201
200202 // reset params
201 if (alsa.device) free(alsa.device);
202 alsa.device = NULL;
203203 alsa.rate = 0;
204204 alsa.period_size = 0;
205 alsa.device = malloc(strlen(device) + 1 + 4); // extra space for changing to plug
206205 strcpy(alsa.device, device);
206
207 if (strlen(device) > MAX_DEVICE_LEN - 4 - 1) {
208 LOG_ERROR("device name too long: %s", device);
209 return -1;
210 }
207211
208212 bool retry;
209213 do {
482486 outputParameters.hostApiSpecificStreamInfo = NULL;
483487
484488 #if OSX
485 // enable pro mode which aims to avoid resampling if possible
489 // enable pro mode which aims to avoid resampling if possible for non built in devices
490 // see http://code.google.com/p/squeezelite/issues/detail?id=11 for reason for not doing with built in device
486491 PaMacCoreStreamInfo macInfo;
487 PaMacCore_SetupStreamInfo(&macInfo, paMacCorePro);
492 unsigned long streamInfoFlags;
493 if (!strcmp(Pa_GetDeviceInfo(outputParameters.device)->name, "Built-in Output")) {
494 LOG_INFO("opening device in PlayNice mode");
495 streamInfoFlags = paMacCorePlayNice;
496 } else {
497 LOG_INFO("opening device in Pro mode");
498 streamInfoFlags = paMacCorePro;
499 }
500 PaMacCore_SetupStreamInfo(&macInfo, streamInfoFlags);
488501 outputParameters.hostApiSpecificStreamInfo = &macInfo;
489502 #endif
490503 }
840853 cross_ptr = (s32_t *)(output.fade_end + cur_f * BYTES_PER_FRAME);
841854 } else {
842855 LOG_INFO("unable to continue crossfade - too few samples");
843 output.fade = FADE_NONE;
856 output.fade = FADE_INACTIVE;
844857 }
845858 }
846859 }
12511264 // if default setting used and nothing in buffer attempt to resize to provide full crossfade support
12521265 LOG_INFO("resize outputbuf for crossfade");
12531266 _buf_resize(outputbuf, OUTPUTBUF_SIZE_CROSSFADE);
1267 #if LINUX
1268 touch_memory(outputbuf->buf, outputbuf->size);
1269 #endif
12541270 }
12551271 }
12561272 }
12791295
12801296 LOCK;
12811297
1282 output.state = STOPPED;
1298 output.state = OUTPUT_STOPPED;
12831299 output.current_sample_rate = 44100;
12841300 output.device = device;
12851301 output.fade = FADE_INACTIVE;
13261342 LOG_INFO("output: %s maxrate: %u", output.device, output.max_sample_rate);
13271343
13281344 #if ALSA
1345
1346 #if LINUX
1347 // RT linux - aim to avoid pagefaults by locking memory:
1348 // https://rt.wiki.kernel.org/index.php/Threaded_RT-application_with_memory_locking_and_stack_handling_example
1349 if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
1350 LOG_INFO("unable to lock memory: %s", strerror(errno));
1351 } else {
1352 LOG_INFO("memory locked");
1353 }
1354
1355 mallopt(M_TRIM_THRESHOLD, -1);
1356 mallopt(M_MMAP_MAX, 0);
1357
1358 touch_memory(silencebuf, MAX_SILENCE_FRAMES * BYTES_PER_FRAME);
1359 touch_memory(outputbuf->buf, outputbuf->size);
1360 #endif
1361
1362 // start output thread
13291363 pthread_attr_t attr;
13301364 pthread_attr_init(&attr);
1331 pthread_attr_setstacksize(&attr, STREAM_THREAD_STACK_SIZE);
1365 pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + OUTPUT_THREAD_STACK_SIZE);
13321366 pthread_create(&thread, &attr, output_thread, max_rate ? "probe" : NULL);
13331367 pthread_attr_destroy(&attr);
13341368
13401374 } else {
13411375 LOG_DEBUG("set output sched fifo rt: %u", param.sched_priority);
13421376 }
1343
1344 // try to lock memory into RAM to avoid delay on page faults, only works as root or if user has permission
1345 if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
1346 LOG_INFO("unable to lock memory: %s", strerror(errno));
1347 } else {
1348 LOG_INFO("memory locked");
1349 }
13501377 #endif
13511378
13521379 #if PORTAUDIO
1717 *
1818 */
1919
20 #define VERSION "v1.0rc1"
20 #define VERSION "v1.0rc2"
2121
2222 // build detection
2323 #if defined(linux)
126126 #include <pthread.h>
127127 #include <signal.h>
128128
129 #define STREAM_THREAD_STACK_SIZE (PTHREAD_STACK_MIN * 4)
130 #define DECODE_THREAD_STACK_SIZE (PTHREAD_STACK_MIN * 8)
131 #define OUTPUT_THREAD_STACK_SIZE (PTHREAD_STACK_MIN * 4)
129 #define STREAM_THREAD_STACK_SIZE 64 * 1024
130 #define DECODE_THREAD_STACK_SIZE 128 * 1024
131 #define OUTPUT_THREAD_STACK_SIZE 64 * 1024
132132 #define thread_t pthread_t;
133133 #define closesocket(s) close(s)
134134 #define last_error() errno
288288 void *dlsym(void *handle, const char *symbol);
289289 char *dlerror(void);
290290 int poll(struct pollfd *fds, unsigned long numfds, int timeout);
291 #endif
292 #if LINUX
293 void touch_memory(u8_t *buf, size_t size);
291294 #endif
292295
293296 // buffer.c
271271
272272 stream.state = STOPPED;
273273 stream.header = malloc(MAX_HEADER);
274 *stream.header = '\0';
274275
275276 fd = -1;
277
278 #if LINUX
279 touch_memory(streambuf->buf, streambuf->size);
280 #endif
276281
277282 #if LINUX || OSX
278283 pthread_attr_t attr;
279284 pthread_attr_init(&attr);
280 pthread_attr_setstacksize(&attr, STREAM_THREAD_STACK_SIZE);
285 pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + STREAM_THREAD_STACK_SIZE);
281286 pthread_create(&thread, &attr, stream_thread, NULL);
282287 pthread_attr_destroy(&attr);
283288 #endif
316316
317317 #endif
318318
319 #if LINUX
320 void touch_memory(u8_t *buf, size_t size) {
321 u8_t *ptr;
322 for (ptr = buf; ptr < buf + size; ptr += sysconf(_SC_PAGESIZE)) {
323 *ptr = 0;
324 }
325 }
326 #endif
104104 if ((err = v->ov_open_callbacks(streambuf, v->vf, NULL, 0, cbs)) < 0) {
105105 LOG_WARN("open_callbacks error: %d", err);
106106 UNLOCK_O;
107 UNLOCK_S;
107108 return DECODE_COMPLETE;
108109 }
109110