Changeset 4580:435fb7a75ea4 in roaraudio
- Timestamp:
- 11/03/10 05:36:42 (13 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
ChangeLog
r4579 r4580 1 1 v. 0.4beta2 - ? 2 2 * Announce standards via OpenSLP (Closes: #5) 3 * Updated VS API (Closes: #54 )3 * Updated VS API (Closes: #54, #3) 4 4 5 5 v. 0.4beta1 - Mon Nov 01 2010 16:14 CET -
include/libroar/vs.h
r4213 r4580 68 68 */ 69 69 #define roar_vs_new_playback(s,n,r,c,e,b,error) roar_vs_new_simple((s), (n), (r), (c), (e), (b), ROAR_DIR_PLAY, (error)) 70 71 72 /* Attach a open file. 73 */ 74 75 int roar_vs_file(roar_vs_t * vss, struct roar_vio_calls * vio, int closefile, int * error); 76 77 /* Open a file and attach it. 78 */ 79 int roar_vs_file_simple(roar_vs_t * vss, char * filename, int * error); 80 81 /* Connects to a server to just play a file. 82 */ 83 roar_vs_t * roar_vs_new_from_file(const char * server, const char * name, char * filename, int * error); 70 84 71 85 /* Boolean TRUE for VS functions */ … … 201 215 int roar_vs_role (roar_vs_t * vss, int role, int * error); 202 216 217 /* Run a single interation. 218 * This will try to read data from source, write it to the stream 219 * and flush the buffer in buffered mode. 220 * Returns -1 on error, 0 on EOF and positive true value on no error. 221 */ 222 int roar_vs_iterate (roar_vs_t * vss, int wait, int * error); 223 224 /* Iterate untill EOF or error. 225 * Very simple main loop. 226 * Returns 0 on no error and -1 on error. 227 */ 228 int roar_vs_run (roar_vs_t * vss, int * error); 229 203 230 /* Get used connection object 204 231 * This may be usefull if you want to use functions from the main API. -
libroar/vs.c
r4579 r4580 36 36 #include "libroar.h" 37 37 38 #define FLAG_NONE 0x0000 39 #define FLAG_STREAM 0x0001 40 #define FLAG_NONBLOCK 0x0002 41 #define FLAG_BUFFERED 0x0004 38 #define FLAG_NONE 0x0000 39 #define FLAG_STREAM 0x0001 40 #define FLAG_NONBLOCK 0x0002 41 #define FLAG_BUFFERED 0x0004 42 #define FLAG_CLOSEFILE 0x0008 43 #define FLAG_DIR_IN 0x1000 44 #define FLAG_DIR_OUT 0x2000 42 45 43 46 #define _initerr() do { errno = 0; roar_err_clear(); } while(0) … … 57 60 int mixerid; 58 61 int first_primid; 62 struct roar_buffer * readbuffer, * writebuffer; 63 struct roar_vio_calls file_store; 64 struct roar_vio_calls * file; 59 65 }; 60 66 … … 173 179 vss->flags |= FLAG_STREAM; 174 180 181 switch (dir) { 182 case ROAR_DIR_PLAY: vss->flags |= FLAG_DIR_OUT; break; 183 } 184 175 185 return 0; 176 186 } … … 200 210 } 201 211 212 int roar_vs_file(roar_vs_t * vss, struct roar_vio_calls * vio, int closefile, int * error) { 213 _ckvss(-1); 214 215 if ( vio == NULL || (closefile != ROAR_VS_TRUE && closefile != ROAR_VS_FALSE)) { 216 _seterr(ROAR_ERROR_INVAL); 217 return -1; 218 } 219 220 if ( vss->file != NULL ) { 221 _seterr(ROAR_ERROR_INVAL); 222 return -1; 223 } 224 225 vss->file = vio; 226 if ( closefile == ROAR_VS_TRUE ) 227 vss->flags |= FLAG_CLOSEFILE; 228 229 return 0; 230 } 231 232 int roar_vs_file_simple(roar_vs_t * vss, char * filename, int * error) { 233 struct roar_vio_defaults def; 234 struct roar_vio_calls * file; 235 char buf[64]; 236 ssize_t ret; 237 int dir = O_RDONLY; 238 int codec; 239 240 _ckvss(-1); 241 242 if ( vss->file != NULL ) { 243 _seterr(ROAR_ERROR_INVAL); 244 return -1; 245 } 246 247 if ( vss->flags & FLAG_STREAM ) { 248 switch (vss->flags & (FLAG_DIR_IN|FLAG_DIR_OUT)) { 249 case FLAG_DIR_IN: dir = O_WRONLY; break; 250 case FLAG_DIR_OUT: dir = O_RDONLY; break; 251 case FLAG_DIR_IN|FLAG_DIR_OUT: dir = O_RDWR; break; 252 default: return -1; 253 } 254 } 255 256 file = &(vss->file_store); 257 258 // TODO: FIXME: correct error handling bellow. 259 260 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, dir, 0644) == -1 ) 261 return -11; 262 263 if ( roar_vio_open_dstr(file, filename, &def, 1) == -1 ) { 264 return -1; 265 } 266 267 if ( !(vss->flags & FLAG_STREAM) ) { 268 ret = roar_vio_read(file, buf, sizeof(buf)); 269 270 codec = roar_file_codecdetect(buf, ret); 271 272 if ( vss->info.codec == -1 ) { 273 roar_vio_close(file); 274 return -1; 275 } 276 277 memset(&(vss->info), 0, sizeof(vss->info)); 278 279 vss->info.rate = ROAR_RATE_DEFAULT; 280 vss->info.channels = ROAR_CHANNELS_DEFAULT; 281 vss->info.codec = codec; 282 vss->info.bits = ROAR_BITS_DEFAULT; 283 284 if ( roar_vio_lseek(file, 0, SEEK_SET) != 0 ) { 285 roar_vio_close(file); 286 return -1; 287 } 288 289 ret = roar_vs_stream(vss, &(vss->info), ROAR_DIR_PLAY, error); 290 291 if ( ret == -1 ) { 292 roar_vio_close(file); 293 return -1; 294 } 295 } 296 297 if ( roar_vs_file(vss, file, ROAR_VS_TRUE, error) == -1 ) { 298 roar_vio_close(file); 299 return -1; 300 } 301 302 return 0; 303 } 304 305 roar_vs_t * roar_vs_new_from_file(const char * server, const char * name, char * filename, int * error) { 306 roar_vs_t * vss = roar_vs_new(server, name, error); 307 308 if ( vss == NULL ) 309 return NULL; 310 311 if ( roar_vs_file_simple(vss, filename, error) != 0 ) { 312 roar_vs_close(vss, ROAR_VS_TRUE, NULL); 313 return NULL; 314 } 315 316 return vss; 317 } 318 202 319 int roar_vs_close(roar_vs_t * vss, int killit, int * error) { 203 320 if ( killit != ROAR_VS_TRUE && killit != ROAR_VS_FALSE ) { … … 207 324 208 325 _ckvss(-1); 326 327 if ( vss->readbuffer != NULL ) 328 roar_buffer_free(vss->readbuffer); 329 if ( vss->writebuffer != NULL ) 330 roar_buffer_free(vss->writebuffer); 331 332 if ( vss->file != NULL && vss->flags & FLAG_CLOSEFILE ) 333 roar_vio_close(vss->file); 209 334 210 335 if ( vss->flags & FLAG_STREAM ) { … … 746 871 } 747 872 873 874 int roar_vs_iterate (roar_vs_t * vss, int wait, int * error) { 875 struct roar_vio_select vios[3]; 876 struct roar_vio_selecttv rtv = {.sec = 0, .nsec = 1}; 877 size_t len = 0; 878 ssize_t i; 879 ssize_t ret; 880 int can_read = 0, can_write = 0; 881 int can_flush_stream = 0, can_flush_file = 0; 882 int is_eof = 0; 883 void * data; 884 885 _ckvss(-1); 886 887 if ( wait != ROAR_VS_WAIT && wait != ROAR_VS_NOWAIT ) { 888 _seterr(ROAR_ERROR_INVAL); 889 return -1; 890 } 891 892 ROAR_VIO_SELECT_SETVIO(&(vios[len]), &(vss->vio), ((vss->flags & FLAG_DIR_IN ? ROAR_VIO_SELECT_READ : 0) | 893 (vss->flags & FLAG_DIR_OUT ? ROAR_VIO_SELECT_WRITE : 0))); 894 vios[len].ud.vp = &(vss->vio); 895 len++; 896 897 ROAR_VIO_SELECT_SETVIO(&(vios[len]), roar_get_connection_vio2(vss->con), ROAR_VIO_SELECT_READ); 898 vios[len].ud.vp = vss->con; 899 len++; 900 901 902 // TODO: FIXME: need to do two select()s so we can sleep more efficently and test for both directions. 903 // for the moment we disable file direction and hope it will not block anyway... 904 /* 905 if ( vss->file != NULL ) { 906 ROAR_VIO_SELECT_SETVIO(&(vios[len]), vss->file, ((vss->flags & FLAG_DIR_IN ? ROAR_VIO_SELECT_WRITE : 0) | 907 (vss->flags & FLAG_DIR_OUT ? ROAR_VIO_SELECT_READ : 0))); 908 vios[len].ud.vp = vss->file; 909 len++; 910 } 911 */ 912 913 ret = roar_vio_select(vios, len, (wait == ROAR_VS_NOWAIT ? &rtv : NULL), NULL); 914 915 // part 2 of above hack: 916 // emulate read handle. 917 vios[len].ud.vp = vss->file; 918 vios[len].eventsa = ROAR_VIO_SELECT_WRITE|ROAR_VIO_SELECT_READ;; 919 len++; 920 921 // no error here nor EOF. 922 if ( ret == 0 ) 923 return 1; 924 925 for (i = 0; i < len; i++) { 926 if ( !vios[i].eventsa ) 927 continue; 928 929 if ( vios[i].ud.vp == &(vss->vio) ) { 930 if ( vios[i].eventsa & ROAR_VIO_SELECT_READ ) 931 can_read++; 932 933 if ( vios[i].eventsa & ROAR_VIO_SELECT_WRITE ) { 934 can_write++; 935 can_flush_stream = 1; 936 } 937 } else if ( vios[i].ud.vp == vss->con ) { 938 roar_sync(vss->con); 939 } else if ( vios[i].ud.vp == vss->file ) { 940 if ( vios[i].eventsa & ROAR_VIO_SELECT_READ ) 941 can_write++; 942 943 if ( vios[i].eventsa & ROAR_VIO_SELECT_WRITE ) { 944 can_read++; 945 can_flush_file = 1; 946 } 947 } 948 } 949 950 // TODO: FIXME: Need to correct error handling here! 951 952 if ( can_flush_stream && vss->writebuffer != NULL ) { 953 if ( roar_buffer_get_data(vss->writebuffer, &data) == -1 ) 954 return -1; 955 956 if ( roar_buffer_get_len(vss->writebuffer, &len) == -1 ) 957 return -1; 958 959 ret = roar_vs_write(vss, data, len, error); 960 961 if ( ret == -1 ) { 962 return -1; 963 } else if ( ret == len ) { 964 roar_buffer_free(vss->writebuffer); 965 vss->writebuffer = NULL; 966 } else { 967 if ( roar_buffer_set_offset(vss->writebuffer, ret) == -1 ) 968 return -1; 969 } 970 } 971 972 if ( can_flush_file && vss->readbuffer != NULL ) { 973 if ( roar_buffer_get_data(vss->readbuffer, &data) == -1 ) 974 return -1; 975 976 if ( roar_buffer_get_len(vss->readbuffer, &len) == -1 ) 977 return -1; 978 979 ret = roar_vio_write(vss->file, data, len); 980 981 if ( ret == -1 ) { 982 return -1; 983 } else if ( ret == len ) { 984 roar_buffer_free(vss->readbuffer); 985 vss->readbuffer = NULL; 986 } else { 987 if ( roar_buffer_set_offset(vss->readbuffer, ret) == -1 ) 988 return -1; 989 } 990 } 991 992 #define _READ_SIZE 1024 993 994 if ( can_read == 2 && vss->readbuffer == NULL ) { 995 if ( roar_buffer_new_data(&(vss->readbuffer), (len = _READ_SIZE), &data) == -1 ) 996 return -1; 997 998 ret = roar_vs_read(vss, data, len, error); 999 1000 if ( ret == -1 ) { 1001 roar_buffer_free(vss->readbuffer); 1002 vss->readbuffer = NULL; 1003 return -1; 1004 } else if ( ret == 0 ) { 1005 is_eof = 1; 1006 roar_buffer_free(vss->readbuffer); 1007 vss->readbuffer = NULL; 1008 } else { 1009 len = ret; 1010 if ( roar_buffer_set_len(vss->readbuffer, len) == -1 ) 1011 return -1; 1012 1013 ret = roar_vio_write(vss->file, data, len); 1014 1015 if ( ret == -1 ) { 1016 return -1; 1017 } else if ( ret == len ) { 1018 roar_buffer_free(vss->readbuffer); 1019 vss->readbuffer = NULL; 1020 } else { 1021 if ( roar_buffer_set_offset(vss->readbuffer, ret) == -1 ) 1022 return -1; 1023 } 1024 } 1025 } 1026 1027 if ( can_write == 2 && vss->writebuffer == NULL ) { 1028 if ( roar_buffer_new_data(&(vss->writebuffer), (len = _READ_SIZE), &data) == -1 ) 1029 return -1; 1030 1031 ret = roar_vio_read(vss->file, data, len); 1032 1033 if ( ret == -1 ) { 1034 roar_buffer_free(vss->writebuffer); 1035 vss->readbuffer = NULL; 1036 return -1; 1037 } else if ( ret == 0 ) { 1038 is_eof = 1; 1039 roar_buffer_free(vss->writebuffer); 1040 vss->readbuffer = NULL; 1041 } else { 1042 if ( len != ret ) { 1043 len = ret; 1044 if ( roar_buffer_set_len(vss->readbuffer, len) == -1 ) 1045 return -1; 1046 } 1047 1048 ret = roar_vs_write(vss, data, len, error); 1049 1050 if ( ret == -1 ) { 1051 return -1; 1052 } else if ( ret == len ) { 1053 roar_buffer_free(vss->writebuffer); 1054 vss->writebuffer = NULL; 1055 } else { 1056 if ( roar_buffer_set_offset(vss->writebuffer, ret) == -1 ) 1057 return -1; 1058 } 1059 } 1060 } 1061 1062 return is_eof ? 0 : 1; 1063 } 1064 1065 int roar_vs_run (roar_vs_t * vss, int * error) { 1066 int ret; 1067 1068 _ckvss(-1); 1069 1070 while ((ret = roar_vs_iterate(vss, ROAR_VS_WAIT, error)) > 0); 1071 1072 if ( ret == 0 ) { 1073 // flush buffers: 1074 roar_vs_iterate(vss, ROAR_VS_WAIT, error); 1075 } 1076 1077 return ret; 1078 } 1079 1080 748 1081 struct roar_connection * roar_vs_connection_obj(roar_vs_t * vss, int * error) { 749 1082 _ckvss(NULL);
Note: See TracChangeset
for help on using the changeset viewer.