]> git.ipfire.org Git - thirdparty/shairport-sync.git/blame - audio_pipe.c
Update RELEASENOTES.md
[thirdparty/shairport-sync.git] / audio_pipe.c
CommitLineData
0129db08
JL
1/*
2 * pipe output driver. This file is part of Shairport.
3 * Copyright (c) James Laird 2013
4 * All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27#include <stdio.h>
28#include <unistd.h>
29#include <fcntl.h>
30#include <memory.h>
2e27c885 31#include <stdlib.h>
4cd3f5c3 32#include <errno.h>
0cc29d63
MB
33#include <sys/types.h>
34#include <sys/stat.h>
0129db08
JL
35#include "common.h"
36#include "audio.h"
37
28a5afc9 38static int fd = -1;
0129db08
JL
39
40char *pipename = NULL;
41
42static void start(int sample_rate) {
fdbf64e9
MB
43 // this will leave fd as -1 if a reader hasn't been attached
44 fd = open(pipename, O_WRONLY | O_NONBLOCK);
0129db08
JL
45}
46
fdbf64e9
MB
47static void play(short buf[], int samples) {
48 // if the file is not open, try to open it.
49 if (fd == -1) {
50 fd = open(pipename, O_WRONLY | O_NONBLOCK);
51 }
52 // if it's got a reader, write to it.
53 if (fd != -1) {
54 int ignore = non_blocking_write(fd, buf, samples * 4);
55 }
56}
0129db08
JL
57
58static void stop(void) {
fdbf64e9
MB
59// Don't close the pipe just because a play session has stopped.
60// if (fd > 0)
61// close(fd);
0129db08
JL
62}
63
54250f75 64static int init(int argc, char **argv) {
fdbf64e9 65 debug(1, "pipe init");
38281dd1
MB
66 const char *str;
67 int value;
fdbf64e9 68
87a0475c 69 config.audio_backend_buffer_desired_length = 44100; // one second.
54250f75 70 config.audio_backend_latency_offset = 0;
0129db08 71
87a0475c
MB
72 if (config.cfg != NULL) {
73 /* Get the Output Pipename. */
74 const char *str;
75 if (config_lookup_string(config.cfg, "pipe.name", &str)) {
76 pipename = (char *)str;
77 }
fdbf64e9
MB
78
79 if ((pipename) && (strcasecmp(pipename, "STDOUT") == 0))
80 die("Can't use \"pipe\" backend for STDOUT. Use the \"stdout\" backend instead.");
38281dd1
MB
81
82 /* Get the desired buffer size setting. */
83 if (config_lookup_int(config.cfg, "pipe.audio_backend_buffer_desired_length", &value)) {
58a13cf8
MB
84 if ((value < 0) || (value > 132300))
85 die("Invalid pipe audio backend buffer desired length \"%d\". It should be between 0 and 132300, default is 44100",
38281dd1
MB
86 value);
87 else
88 config.audio_backend_buffer_desired_length = value;
89 }
90
91 /* Get the latency offset. */
92 if (config_lookup_int(config.cfg, "pipe.audio_backend_latency_offset", &value)) {
58a13cf8
MB
93 if ((value < -66150) || (value > 66150))
94 die("Invalid pipe audio backend buffer latency offset \"%d\". It should be between -66150 and +66150, default is 0",
38281dd1
MB
95 value);
96 else
97 config.audio_backend_latency_offset = value;
98 }
4cd3f5c3 99 }
fdbf64e9 100
87a0475c
MB
101 if ((pipename == NULL) && (argc != 1))
102 die("bad or missing argument(s) to pipe");
4cd3f5c3 103
87a0475c
MB
104 if (argc == 1)
105 pipename = strdup(argv[0]);
fdbf64e9
MB
106
107
87a0475c 108 // here, create the pipe
fdbf64e9
MB
109 if (mkfifo(pipename, 0644) && errno != EEXIST)
110 die("Could not create output pipe \"%s\"", pipename);
4cd3f5c3 111
87a0475c 112 debug(1, "Pipename is \"%s\"", pipename);
0129db08 113
87a0475c 114 return 0;
0129db08
JL
115}
116
117static void deinit(void) {
fdbf64e9 118 if (fd > 0)
87a0475c 119 close(fd);
0129db08
JL
120}
121
122static void help(void) {
38281dd1 123 printf(" pipe takes 1 argument: the name of the FIFO to write to.\n");
0129db08
JL
124}
125
87a0475c
MB
126audio_output audio_pipe = {.name = "pipe",
127 .help = &help,
128 .init = &init,
129 .deinit = &deinit,
130 .start = &start,
131 .stop = &stop,
132 .flush = NULL,
133 .delay = NULL,
134 .play = &play,
135 .volume = NULL,
136 .parameters = NULL};