Changeset 4744:3df357138d32 in roaraudio


Ignore:
Timestamp:
01/31/11 12:52:03 (13 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

added support to stream audio using gopher

File:
1 edited

Legend:

Unmodified
Added
Removed
  • plugins/roard/protocol-gopher.c

    r4742 r4744  
    4242static int scb_client_info(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem); 
    4343static int scb_stream_info(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem); 
     44static int scb_listen_menu(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem); 
     45static int scb_listen     (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem); 
    4446 
    4547static struct roar_gopher_menu_item g_gopher_root_menu[] = { 
     
    4951 {.type = _DIR,  .name = "Clients",       .selector = "/clients/",   .host = NULL, .port = 0}, 
    5052 {.type = _DIR,  .name = "Streams",       .selector = "/streams/",   .host = NULL, .port = 0}, 
     53 {.type = _DIR,  .name = "Listen!",       .selector = "/listen/",    .host = NULL, .port = 0}, 
    5154}; 
    5255 
     
    8285 {.selector = "/streams/",   .type = _DIR,  .cb = scb_streams}, 
    8386 {.selector = "/clients/*/", .type = _DIR,  .cb = scb_client_info}, 
    84  {.selector = "/streams/*/", .type = _DIR,  .cb = scb_stream_info} 
     87 {.selector = "/streams/*/", .type = _DIR,  .cb = scb_stream_info}, 
     88 {.selector = "/listen/",    .type = _DIR,  .cb = scb_listen_menu}, 
     89 {.selector = "/listen/*/*/*/*/*", .type = _FILE,  .cb = scb_listen} 
    8590}; 
    8691 
     
    417422#undef _MAX_ITEMS 
    418423 return ret; 
     424} 
     425 
     426static int scb_listen_menu(int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem) { 
     427#define _MAX_ITEMS 12 
     428 struct roar_gopher_menu_item items[_MAX_ITEMS]; 
     429 struct roar_gopher_menu menu = {.flags = 0, .items = items, .items_len = 0}; 
     430 struct roar_gopher_menu_item * item; 
     431 const char * codec; 
     432 int ret; 
     433 int codecs[] = {ROAR_CODEC_DEFAULT, ROAR_CODEC_RIFF_WAVE, ROAR_CODEC_AU, ROAR_CODEC_OGG_VORBIS}; 
     434 size_t i; 
     435 
     436 memset(items, 0, sizeof(items)); 
     437 
     438 item = &(items[menu.items_len++]); 
     439 item->type = _INFO; 
     440 item->name = roar_mm_strdup("Select a format you want to listen in:"); 
     441 
     442 item = &(items[menu.items_len++]); 
     443 item->type = _INFO; 
     444 item->name = NULL; // empty lion 
     445 
     446 for (i = 0; i < (sizeof(codecs)/sizeof(*codecs)); i++) { 
     447  item = &(items[menu.items_len++]); 
     448  item->type = _SOUND; 
     449  codec = roar_codec2str(codecs[i]); 
     450  item->name = _aprintf(64, "%u channels with %u bits at %uHz, %s", 
     451                            g_sa->channels, g_sa->bits, g_sa->rate, codec); 
     452  item->selector = _aprintf(64, "/listen/monitor/%u/%u/%u/%s", g_sa->rate, g_sa->bits, g_sa->channels, codec); 
     453 } 
     454 
     455 ret = send_menu(client, &menu, vio); 
     456 
     457 for (i = 0; i < menu.items_len; i++) { 
     458  if ( items[i].name != NULL ) 
     459   roar_mm_free((void*)items[i].name); 
     460  if ( items[i].selector != NULL ) 
     461   roar_mm_free((void*)items[i].selector); 
     462 } 
     463 
     464#undef _MAX_ITEMS 
     465 return ret; 
     466} 
     467 
     468static int scb_listen     (int client, struct roar_vio_calls * vio, char * selector, char ** text, struct item * sitem) { 
     469 struct roar_stream_server * ss; 
     470 struct roar_stream        * s; 
     471 struct roar_audio_info info; 
     472 int dir = -1; 
     473 ssize_t toks; 
     474 char * tok[5]; 
     475 int stream = -1; 
     476 
     477 toks = strseltok(sitem->selector, selector, tok, 5); 
     478 
     479 if ( toks != 5 ) 
     480  return -1; 
     481 
     482 memset(&info, 0, sizeof(info)); 
     483 
     484 if ( (dir = roar_str2dir(tok[0])) == -1 ) 
     485  return -1; 
     486 
     487 // test for unsupported dirs: 
     488 switch (dir) { 
     489  case ROAR_DIR_THRU: 
     490  case ROAR_DIR_RAW_IN: 
     491  case ROAR_DIR_FILTER: 
     492    return -1; 
     493   break; 
     494 } 
     495 
     496 info.rate     = atoi(tok[1]); 
     497 info.bits     = atoi(tok[2]); 
     498 info.channels = atoi(tok[3]); 
     499 info.codec    = roar_str2codec(tok[4]); 
     500 
     501 if ( info.codec == -1 ) 
     502  return -1; 
     503 
     504 if ((stream = streams_new()) == -1 ) 
     505  return -1; 
     506 
     507 if ( streams_get(stream, &ss) == -1 ) { 
     508  streams_delete(stream); 
     509  return -1; 
     510 } 
     511 
     512 s = ROAR_STREAM(ss); 
     513 
     514 if ( client_stream_add(client, stream) == -1 ) { 
     515  streams_delete(stream); 
     516  return -1; 
     517 } 
     518 
     519 memcpy(&(s->info), &info, sizeof(info)); 
     520 ss->codec_orgi = info.codec; 
     521 
     522 if ( streams_set_dir(stream, dir, 1) == -1 ) { 
     523  streams_delete(stream); 
     524  return -1; 
     525 } 
     526 
     527 if ( client_stream_exec(client, stream) == -1 ) { 
     528  streams_delete(stream); 
     529  return -1; 
     530 } 
     531 
     532 return 0; 
    419533} 
    420534 
     
    537651 struct roar_buffer * buf; 
    538652 struct roar_gopher_menu_item * item; 
    539  const size_t len = 80; 
     653 const size_t len = 256; 
    540654 size_t i; 
    541655 void * data; 
     
    561675  switch (item->type) { 
    562676   case _INFO: 
    563      snprintf(data, len-1, "i%s\tfake\t(NULL)\t0\r\n", item->name); 
     677     snprintf(data, len-1, "i%s\tfake\t(NULL)\t0\r\n", item->name == NULL ? "" : item->name); 
    564678    break; 
    565679   default: 
Note: See TracChangeset for help on using the changeset viewer.