source: roaraudio/libroar/file.c @ 636:4a2ecb926a0e

Last change on this file since 636:4a2ecb926a0e was 636:4a2ecb926a0e, checked in by phi, 16 years ago

added ROAR_CELT_MAGIC :)

File size: 2.9 KB
Line 
1//file.c:
2
3#include "libroar.h"
4
5#define BUFSIZE 8192
6#define BUFMAX  65536
7
8int roar_file_codecdetect(char * buf, int len) {
9 int codec = -1;
10
11 if ( len > 3 ) {
12  if ( strncmp(buf, "OggS", 4) == 0 ) {
13   codec = ROAR_CODEC_OGG_GENERAL;
14   if ( len > 34 ) { // this is 7 bytes after the end of the header
15    if ( strncmp(buf+28, "\001vorbis", 7) == 0 )
16     codec = ROAR_CODEC_OGG_VORBIS;
17   }
18  } else if ( strncmp(buf, "MThd", 4) == 0 ) {
19   codec = ROAR_CODEC_MIDI_FILE;
20  } else if ( strncmp(buf, "RIFF", 4) == 0 ) {
21   if ( len > 15 ) {
22    if ( strncmp(buf+8, "WAVEfmt ", 8) == 0 )
23     codec = ROAR_CODEC_RIFF_WAVE;
24   }
25  } else if ( strncmp(buf, "Roar", 4) == 0 ) {
26   if ( len > ROAR_SPEEX_MAGIC_LEN ) {
27    if ( strncmp(buf, ROAR_SPEEX_MAGIC, ROAR_SPEEX_MAGIC_LEN) == 0 )
28     codec = ROAR_CODEC_ROAR_SPEEX;
29#if ROAR_SPEEX_MAGIC_LEN < ROAR_CELT_MAGIC_LEN
30   }
31   if ( len > ROAR_CELT_MAGIC_LEN ) {
32#endif
33    if ( strncmp(buf, ROAR_CELT_MAGIC, ROAR_CELT_MAGIC_LEN) == 0 )
34     codec = ROAR_CODEC_ROAR_CELT;
35   }
36  }
37 }
38
39 return codec;
40}
41
42ssize_t roar_file_send_raw (int out, int in) {
43 ssize_t r = 0;
44 ssize_t ret;
45 int len;
46 char buf[BUFSIZE];
47#ifdef __linux__
48 int cork_new = 1, cork_old;
49 socklen_t cork_len = sizeof(int);
50
51 if ( getsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, &cork_len) == -1 ) {
52  cork_old = -1;
53 } else {
54  setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_new, sizeof(int));
55 }
56#endif
57
58#ifdef ROAR_HAVE_LINUX_SENDFILE
59 while ((ret = sendfile(out, in, NULL, BUFMAX)) > 0)
60  r += ret;
61#endif
62
63 // TODO: try mmap here!
64
65 while ((len = read(in, buf, BUFSIZE)) > 0)
66  r += write(out, buf, len);
67
68#ifdef __linux__
69 if ( cork_old != -1 )
70  setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, cork_len);
71#endif
72 return r;
73}
74
75ssize_t roar_file_play (struct roar_connection * con, char * file, int exec) {
76 int codec = -1;
77 int in, out = -1;
78 struct roar_stream s;
79 ssize_t r = 0;
80 int len;
81 char buf[BUFSIZE];
82 int rate = ROAR_RATE_DEFAULT, channels = ROAR_CHANNELS_DEFAULT, bits = ROAR_BITS_DEFAULT;
83
84 if ( !con )
85  return -1;
86
87 if ( !file )
88  return -1;
89
90 if ( (in = open(file, O_RDONLY, 0644)) == -1 ) {
91  return -1;
92 }
93
94 if ((len = read(in, buf, BUFSIZE)) < 1) {
95  close(in);
96  return -1;
97 }
98
99 codec = roar_file_codecdetect(buf, len);
100
101 if ( codec == -1 ) {
102  close(in);
103  return -1;
104 }
105
106 if ( exec ) {
107  if ( roar_stream_new(&s, rate, channels, bits, codec) == -1 ) {
108   close(in);
109   return -1;
110  }
111
112  if ( roar_stream_connect(con, &s, ROAR_DIR_PLAY) == -1 ) {
113   close(in);
114   return -1;
115  }
116
117  if ( roar_stream_exec(con, &s) == -1 ) {
118   close(in);
119   return -1;
120  }
121
122  shutdown(con->fh, SHUT_RD);
123
124  out = con->fh;
125 } else {
126  if ( (out = roar_simple_new_stream(con, rate, channels, bits, codec, ROAR_DIR_PLAY)) == -1 ) {
127   close(in);
128   return -1;
129  }
130 }
131
132 write(out, buf, len);
133
134 r = roar_file_send_raw(out, in);
135
136 close(out);
137
138 if ( exec ) {
139  con->fh = -1;
140 }
141
142 close(in);
143
144 return r;
145}
146
147//ll
Note: See TracBrowser for help on using the repository browser.