int main(int argc, char **argv) { size_t c; int status; // Default values. arguments.verbose = DEBUG_LEVEL_INFO; arguments.port = 0; arguments.channel = 0; arguments.channel2 = arguments.channel + 1; arguments.packetsize = 1024; arguments.period_size = 512; arguments.nb_periods = 2; // number of extra frames to buffer on top of the // nb_periods x period_size. adds to the latency arguments.frame_slack = 0; // number of extra ISO packet descriptors to queue, // doesn't add to the latency. arguments.iso_slack = 0; arguments.startoncycle = -1; arguments.countdown = 4; arguments.printinterval = 100; arguments.rtprio = 0; // Parse our arguments; every option seen by `parse_opt' will // be reflected in `arguments'. if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) { debugError("Could not parse command line\n" ); return -1; } // utility file descriptor char *device = NULL; if(asprintf(&device, "/dev/fw%zd", arguments.port) < 0) { debugError("Failed create device string\n"); exit(-1); } // open the specified port debugOutput(DEBUG_LEVEL_INFO, "Open device %s...\n", device); int util_fd = open( device, O_RDWR ); if(util_fd < 0) { debugError("Failed to open %s\n", device); free(device); exit(-1); } free(device); setDebugLevel(arguments.verbose); // AM824 settings struct am824_settings stream_settings; stream_settings.syt_interval = 8; // connection settings struct stream_settings settings; settings.type = STREAM_TYPE_RECEIVE; settings.channel = 0; settings.port = arguments.port; settings.max_packet_size = arguments.packetsize; settings.client_data = &stream_settings; settings.process_header = NULL; settings.process_payload = receive_am824_packet_data; settings.packet_size_for_sync = FRAMES_PER_PACKET; // setup the streamer streamer_t strm = streamer_new(); if(strm == NULL) { debugError("Could not allocate streamer\n"); exit(-1); } __u32 conn_ids[16]; if(streamer_init(strm, arguments.port, arguments.period_size, arguments.nb_periods, arguments.frame_slack, arguments.iso_slack, FRAMES_PER_SECOND) < 0) { debugError("Failed to init streamer\n"); close(util_fd); exit(-1); } #if 0 settings.channel = arguments.channel; settings.type = STREAM_TYPE_TRANSMIT; settings.process_header = NULL; settings.process_payload = transmit_am824_packet_data; #else settings.channel = 0; settings.type = STREAM_TYPE_RECEIVE; settings.process_header = NULL; settings.process_payload = receive_am824_packet_data; #endif status = streamer_add_stream(strm, &settings); if(status < 0) { debugError("Failed to add connection\n"); streamer_free(strm); close(util_fd); exit(-1); } conn_ids[0] = status; #if 1 settings.channel = arguments.channel2; settings.type = STREAM_TYPE_TRANSMIT; settings.process_header = NULL; settings.process_payload = transmit_am824_packet_data; #else settings.channel = 1; settings.type = STREAM_TYPE_RECEIVE; settings.process_header = NULL; settings.process_payload = receive_am824_packet_data; #endif status = streamer_add_stream(strm, &settings); if(status < 0) { debugError("Failed to add connection\n"); streamer_free(strm); close(util_fd); exit(-1); } conn_ids[1] = status; #if 0 settings.channel = 12; settings.type = STREAM_TYPE_TRANSMIT; settings.process_header = NULL; settings.process_payload = transmit_am824_packet_data; #else settings.channel = arguments.channel; settings.type = STREAM_TYPE_RECEIVE; settings.process_header = NULL; settings.process_payload = receive_am824_packet_data; #endif status = streamer_add_stream(strm, &settings); if(status < 0) { debugError("Failed to add connection\n"); streamer_free(strm); close(util_fd); exit(-1); } conn_ids[2] = status; streamer_start_connection(strm, conn_ids[0], -1); streamer_set_sync_connection(strm, conn_ids[0]); int nruns = arguments.countdown; // start the streamer if(streamer_start(strm) < 0) { debugError("Could not start streamer\n"); return -1; } do { // debugOutput(DEBUG_LEVEL_INFO, debugWarning( ">>>>>>>>>> Run %d <<<<<<<<<<\n", (int)(arguments.countdown - nruns)); if(arguments.countdown - nruns == 10) { streamer_start_connection(strm, conn_ids[1], -1); } if(arguments.countdown - nruns == 20) { streamer_start_connection(strm, conn_ids[2], -1); } if(arguments.countdown - nruns == 30) { settings.channel = 3; settings.type = STREAM_TYPE_RECEIVE; settings.process_header = NULL; settings.process_payload = receive_am824_packet_data; status = streamer_add_stream(strm, &settings); if(status < 0) { debugError("Failed to add connection\n"); streamer_free(strm); close(util_fd); exit(-1); } conn_ids[3] = status; } if(arguments.countdown - nruns == 40) { streamer_start_connection(strm, conn_ids[3], -1); } if(arguments.countdown - nruns == 50) { streamer_set_sync_connection(strm, conn_ids[3]); } /* ============================== * * WAIT * * ============================== */ if(streamer_wait_for_period(strm) < 0) { debugError("Failed to wait for period\n"); goto out; } /* ============================== * * READ * * ============================== */ streamer_read_frames(strm); /* ============================== * * PROCESS * * ============================== */ /* ============================== * * WRITE * * ============================== */ streamer_write_frames(strm); /* ============================== * * REQUEUE * * ============================== */ if(streamer_queue_next_period(strm) < 0) { debugError("queue failed\n"); goto out; } } while(--nruns); out: if(streamer_stop(strm) < 0) { debugError("Could not stop streamer\n"); return -1; } streamer_free(strm); close(util_fd); return 0; }
void player_mainloop (void) { for (;;) { uint32_t msg; uintptr_t ctx; uint32_t p1; uint32_t p2; int term = 0; while (messagepump_pop(&msg, &ctx, &p1, &p2) != -1) { // broadcast to all plugins DB_plugin_t **plugs = plug_get_list (); for (int n = 0; plugs[n]; n++) { if (plugs[n]->message) { plugs[n]->message (msg, ctx, p1, p2); } } if (!term) { DB_output_t *output = plug_get_output (); switch (msg) { case DB_EV_REINIT_SOUND: plug_reinit_sound (); streamer_reset (1); conf_save (); break; case DB_EV_TERMINATE: { save_resume_state (); pl_playqueue_clear (); // stop streaming and playback before unloading plugins DB_output_t *output = plug_get_output (); output->stop (); streamer_free (); output->free (); term = 1; } break; case DB_EV_PLAY_CURRENT: streamer_play_current_track (); break; case DB_EV_PLAY_NUM: pl_playqueue_clear (); streamer_set_nextsong (p1, 4); break; case DB_EV_STOP: streamer_set_nextsong (-2, 0); break; case DB_EV_NEXT: streamer_move_to_nextsong (1); break; case DB_EV_PREV: streamer_move_to_prevsong (1); break; case DB_EV_PAUSE: if (output->state () != OUTPUT_STATE_PAUSED) { output->pause (); messagepump_push (DB_EV_PAUSED, 0, 1, 0); } break; case DB_EV_TOGGLE_PAUSE: if (output->state () == OUTPUT_STATE_PAUSED) { streamer_play_current_track (); } else { output->pause (); messagepump_push (DB_EV_PAUSED, 0, 1, 0); } break; case DB_EV_PLAY_RANDOM: streamer_move_to_randomsong (1); break; case DB_EV_PLAYLIST_REFRESH: pl_save_current (); messagepump_push (DB_EV_PLAYLISTCHANGED, 0, 0, 0); break; case DB_EV_CONFIGCHANGED: conf_save (); streamer_configchanged (); junk_configchanged (); break; case DB_EV_SEEK: streamer_set_seek (p1 / 1000.f); break; } } if (msg >= DB_EV_FIRST && ctx) { messagepump_event_free ((ddb_event_t *)ctx); } } if (term) { return; } messagepump_wait (); } }