source: roaraudio/libroar/file.c @ 558:d3f2d3ecbfcd

Last change on this file since 558:d3f2d3ecbfcd was 558:d3f2d3ecbfcd, checked in by phi, 16 years ago

added support to detect MIDI files

File size: 2.3 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  }
21 }
22
23 return codec;
24}
25
26ssize_t roar_file_send_raw (int out, int in) {
27 ssize_t r = 0;
28 ssize_t ret;
29 int len;
30 char buf[BUFSIZE];
31#ifdef __linux__
32 int cork_new = 1, cork_old;
33 socklen_t cork_len = sizeof(int);
34
35 if ( getsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, &cork_len) == -1 ) {
36  cork_old = -1;
37 } else {
38  setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_new, sizeof(int));
39 }
40#endif
41
42#ifdef ROAR_HAVE_LINUX_SENDFILE
43 while ((ret = sendfile(out, in, NULL, BUFMAX)) > 0)
44  r += ret;
45#endif
46
47 // TODO: try mmap here!
48
49 while ((len = read(in, buf, BUFSIZE)) > 0)
50  r += write(out, buf, len);
51
52#ifdef __linux__
53 if ( cork_old != -1 )
54  setsockopt(out, IPPROTO_TCP, TCP_CORK, &cork_old, cork_len);
55#endif
56 return r;
57}
58
59ssize_t roar_file_play (struct roar_connection * con, char * file, int exec) {
60 int codec = -1;
61 int in, out = -1;
62 struct roar_stream s;
63 ssize_t r = 0;
64 int len;
65 char buf[BUFSIZE];
66 int rate = ROAR_RATE_DEFAULT, channels = ROAR_CHANNELS_DEFAULT, bits = ROAR_BITS_DEFAULT;
67
68 if ( !con )
69  return -1;
70
71 if ( !file )
72  return -1;
73
74 if ( (in = open(file, O_RDONLY, 0644)) == -1 ) {
75  return -1;
76 }
77
78 if ((len = read(in, buf, BUFSIZE)) < 1) {
79  close(in);
80  return -1;
81 }
82
83 codec = roar_file_codecdetect(buf, len);
84
85 if ( codec == -1 ) {
86  close(in);
87  return -1;
88 }
89
90 if ( exec ) {
91  if ( roar_stream_new(&s, rate, channels, bits, codec) == -1 ) {
92   close(in);
93   return -1;
94  }
95
96  if ( roar_stream_connect(con, &s, ROAR_DIR_PLAY) == -1 ) {
97   close(in);
98   return -1;
99  }
100
101  if ( roar_stream_exec(con, &s) == -1 ) {
102   close(in);
103   return -1;
104  }
105
106  shutdown(con->fh, SHUT_RD);
107
108  out = con->fh;
109 } else {
110  if ( (out = roar_simple_new_stream(con, rate, channels, bits, codec, ROAR_DIR_PLAY)) == -1 ) {
111   close(in);
112   return -1;
113  }
114 }
115
116 write(out, buf, len);
117
118 r = roar_file_send_raw(out, in);
119
120 close(out);
121
122 if ( exec ) {
123  con->fh = -1;
124 }
125
126 close(in);
127
128 return r;
129}
130
131//ll
Note: See TracBrowser for help on using the repository browser.