Esempio n. 1
0
static int
xrun_recovery (snd_pcm_t * handle, int err)
{
  if (err == -EPIPE)
    {                           /* under-run */
      err = snd_pcm_prepare (handle);
      if (err < 0)
        alsaplayer_error ("Can't recovery from underrun, prepare failed: %s",
                          snd_strerror (err));
      return 0;
    }
  else if (err == -ESTRPIPE)
    {
      while ((err = snd_pcm_resume (handle)) == -EAGAIN)
        sleep (1);              /* wait until the suspend flag is released */
      if (err < 0)
        {
          err = snd_pcm_prepare (handle);
          if (err < 0)
            alsaplayer_error
              ("Can't recovery from suspend, prepare failed: %s",
               snd_strerror (err));
        }
      return 0;
    }
  return err;
}
Esempio n. 2
0
void load_scope_addons()
{
	char path[1024];
	struct stat buf;
	scope_plugin *tmp;

	scope_plugin_info_type scope_plugin_info;

	snprintf(path, sizeof(path)-1, "%s/scopes2", addon_dir);

	DIR *dir = opendir(path);
	dirent *entry;

	if (dir) {
		while ((entry = readdir(dir)) != NULL) { // For each file in scopes
			if (strcmp(entry->d_name, ".") == 0 ||
				strcmp(entry->d_name, "..") == 0) {
				continue;
			}
			snprintf(path, sizeof (path), "%s/scopes2/%s", addon_dir, entry->d_name);
			//alsaplayer_error(path);
			if (stat(path, &buf)) continue;
			if (S_ISREG(buf.st_mode)) {
				void *handle;

				char *ext = strrchr(path, '.');
				if (!ext)
					continue;
				ext++;
				if (strcasecmp(ext, "so"))
					continue;
				if ((handle = dlopen(path, RTLD_NOW |RTLD_GLOBAL))) {
					scope_plugin_info = (scope_plugin_info_type) dlsym(handle, "scope_plugin_info");
					if (scope_plugin_info) {
#ifdef DEBUG
						alsaplayer_error("Loading scope addon: %s\n", path);
#endif
						tmp = scope_plugin_info();
						if (tmp) {
								tmp->handle = handle;
								if (apRegisterScopePlugin(tmp) == -1) {
									alsaplayer_error("%s is deprecated", path);
								}
						}
					} else {
						dlclose(handle);
					}
				} else {
					printf("%s\n", dlerror());
				}
			}
		}
		closedir(dir);
	}
}
Esempio n. 3
0
/* Receive response head.					       */
static int get_response_head (int sock, char *response, int max)
{
    int len = 0;

    while (len < 4 || memcmp (response + len - 4, "\r\n\r\n", 4)) {
	/* check for overflow */
	if (len >= max) {
	    alsaplayer_error ("HTTP: Response is too long.");
	    return 1;
	}

	/* wait for data */
	if (sleep_for_data (sock))  return 1;

	/* read */
	if (read (sock, response + len, 1) <=0 )
	    break;

	len += 1;
    }

    /* terminate string */
    response [len] = '\0';

    return 0;
} /* end of: get_response_head */
Esempio n. 4
0
static int mad_stream_info(input_object *obj, stream_info *info)
{
	struct mad_local_data *data;	
	unsigned len;
	char metadata[256];
	char *s, *p;

	if (!obj || !info)
		return 0;

	data = (struct mad_local_data *)obj->local_data;

	if (data) {
		if (!data->parse_id3) {
			sprintf(data->sinfo.title, "%s", data->filename);
		} else if (!data->parsed_id3) {
			if (reader_seekable(data->mad_fd)) {
				parse_id3 (data->path, &data->sinfo);
				if ((len = strlen(data->sinfo.title))) {
					s = data->sinfo.title + (len - 1);
					while (s != data->sinfo.title && *s == ' ')
						*(s--) = '\0';
				}
				if ((len = strlen(data->sinfo.artist))) {
					s = data->sinfo.artist + (len - 1);
					while (s != data->sinfo.artist && *s == ' ')
						*(s--) = '\0';
				}
			}
			strncpy (data->sinfo.path, data->path, sizeof(data->sinfo.path));
			data->parsed_id3 = 1;
		}
		memset(metadata, 0, sizeof(metadata));
		if ((len = reader_metadata(data->mad_fd, sizeof(metadata), metadata))) {
			//alsaplayer_error("Metadata: %s", metadata);
			if ((s = strstr(metadata, "StreamTitle='"))) {
				s += 13;
				if ((p = strstr(s, "'"))) {
					*p = '\0';
					snprintf(data->sinfo.title, 128, "%s", s);
				} else {
					alsaplayer_error("Malformed metadata: \"%s\"", metadata);
				}
			}
		}	
		/* Restore permanently filled info */
		memcpy (info, &data->sinfo, sizeof (data->sinfo));

		/* Compose path, stream_type and status fields */
		sprintf(info->stream_type, "MP3 %dKHz %s %-3ldkbit",
				data->frame.header.samplerate / 1000,
				obj->nr_channels == 2 ? "stereo" : "mono",
				data->frame.header.bitrate / 1000);

		if (data->seeking)
			sprintf(info->status, "Seeking...");
	}				
	return 1;
}
static void oglspectrum_start(void)
{
	if (pthread_mutex_trylock(&scope_mutex) != 0) {
		alsaplayer_error("spectrum already running");
		return;
	}
	start_display();
}
Esempio n. 6
0
void exit_sighandler(int x)
{
    static int sigcount = 0;

    ++sigcount;
    if (sigcount == 1) {
        alsaplayer_error("alsaplayer interrupted by signal %d", x);
        exit(1);
    }
    if (sigcount > 5) {
        kill(getpid(), SIGKILL);
    }
}
static void wait_for_vsync(void)
{
#ifdef NVIDIA_SYNC
	static int init = 0;
	static int fd = -1;
	static struct pollfd pollfds;
	if (!init) {
		fd = open("/dev/nvidia0", O_RDONLY);
		if (fd == -1) {
			alsaplayer_error("Error opening NVIDIA device /dev/nvidia0");
		} else {
			pollfds.fd = fd;
			pollfds.events = 0xffff;
			pollfds.revents = 0xffff;
			alsaplayer_error("Using NVIDIA poll method for vsync");
		}
		init = 1;
	}
	poll (&pollfds, 1, -1);
#else
	dosleep(10000);
#endif
}
Esempio n. 8
0
int interface_gtk_start(Playlist *playlist, int argc, char **argv)
{
	char path[256];
	char *home;

	the_coreplayer = playlist->GetCorePlayer();

	g_thread_init(NULL);
	if (!g_thread_supported()) {
		alsaplayer_error("Sorry - this interface requires working threads.\n");
		return 1;
	}

	// Scope functions
	scopes = new AlsaSubscriber();
	scopes->Subscribe(the_coreplayer->GetNode(), POS_END);
	scopes->EnterStream(scope_feeder_func, the_coreplayer);

	gtk_set_locale();
	gtk_init(&argc, &argv);
	gdk_rgb_init();

	home = getenv("HOME");
	if (home) {
		snprintf(path, 255, "%s/.gtkrc", home);
		gtk_rc_parse(path);
	}

	if (playlist->Length())
		playlist->UnPause();
	// Scope addons
	gdk_flush();
	GDK_THREADS_ENTER();
	init_main_window(playlist);
	load_scope_addons();
	gdk_flush();
	gtk_main();
	gdk_flush();
	GDK_THREADS_LEAVE();
	unload_scope_addons();
	destroy_scopes_window();
	GDK_THREADS_ENTER();
	gdk_flush();
	GDK_THREADS_LEAVE();

	playlist->Pause();

	dl_close_scopes();
	return 0;
}
Esempio n. 9
0
interface_plugin_info_type load_interface(const char *name)
{
    void *handle;
    char path[1024];
    const char *pluginroot;
    struct stat statbuf;

    interface_plugin_info_type plugin_info;
    interface_plugin *ui;

    if (!global_pluginroot)
        pluginroot = ADDON_DIR;
    else
        pluginroot = global_pluginroot;

    if (!name)
        return NULL;

    if (strchr(name, '.'))
        ap_strlcpy(path, name, sizeof(path));
    else
        snprintf(path, sizeof(path), "%s/interface/lib%s_interface.so", pluginroot, name);
#ifdef DEBUG
    alsaplayer_error("Loading interface plugin: %s\n", path);
#endif
    if (stat(path, &statbuf) != 0)	// Error reading object
        return NULL;

    handle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
    if (!handle) {
        alsaplayer_error("%s\n", dlerror());
        return NULL;
    }

    plugin_info = (interface_plugin_info_type) dlsym(handle, "interface_plugin_info");
    if (!plugin_info) {
        alsaplayer_error("symbol error in shared object: %s", path);
        dlclose(handle);
        return NULL;
    }

    interface_plugin *plugin = plugin_info();
    if (plugin)
        plugin->handle = handle;
    ui = plugin_info();
    if (ui->version != INTERFACE_PLUGIN_VERSION) {
        alsaplayer_error("Wrong interface plugin version (v%d, wanted v%d)",
                         ui->version,
                         INTERFACE_PLUGIN_VERSION - INTERFACE_PLUGIN_BASE_VERSION);
        alsaplayer_error("Error loading %s", path);
        alsaplayer_error("Please remove this file from your system");
        return NULL;
    }

    return plugin_info;
}
Esempio n. 10
0
/* Sleep for data.                                                     */
static int sleep_for_data (int sock)
{
    fd_set set;
    struct timeval tv;

    tv.tv_sec = 5;
    tv.tv_usec = 0;
    FD_ZERO (&set);
    FD_SET (sock, &set);

    if (select (sock+1, &set, NULL, NULL, &tv) < 1) {
	alsaplayer_error ("HTTP: Connection is too slow.");
	return 1;
    }

    return 0;
} /* end of: sleep_for_data */
Esempio n. 11
0
/* Parse URI.                                                           */
static int parse_uri (const char *uri, char **host, int *port, char **path)
{
    char *slash, *colon;
    int l;

    *port = 80;

     /* Trying to find end of a host part */
    slash = strchr (uri+7, '/');
    colon = strchr (uri+7, ':');

    if ((slash && colon && slash > colon) || (!slash && colon)) {
	/* As I see, there is port specified */
	char *s;

	*port = (int)strtol (colon+1, &s, 10);

	/* Test, port should be digit */
	if ((slash && s!=slash) || (!slash && *s!='\0')) {
	    alsaplayer_error ("\nHTTP: Couldn't open %s: Port -- parse error.", uri);
	    return -1;
	}

	/* Calculate host part length */
	l = colon - uri - 7;
    } else {
	/* Calculate host part length */
	l = slash  ?  slash - uri - 7  :  (int) strlen (uri+7);
    }

    /* Reset port if URI looks like 'foo.bar:/aaa.mp3' */
    if (colon && slash && slash==colon+1)
	*port = 80;

    /* Split URI */
    //if (*host)
    //	    free(*host);
    *host = malloc (l+1);
    ap_strlcpy (*host, uri+7, l+1);

    //if (*path)
    //	    free(*path);
    *path = strdup (slash ? slash : "/");
    return 0;
} /* end of: parse_uri */
Esempio n. 12
0
static ssize_t find_initial_frame(uint8_t *buf, int size)
{
	uint8_t *data = buf;			
	int ext_header = 0;
	int pos = 0;
	ssize_t header_size = 0;
	while (pos < (size - 10)) {
		if (pos == 0 && data[pos] == 0x0d && data[pos+1] == 0x0a)
			pos += 2;
		if (data[pos] == 0xff && (data[pos+1] == 0xfb
					|| data[pos+1] == 0xfa
					|| data[pos+1] == 0xf3 
					|| data[pos+1] == 0xf2
					|| data[pos+1] == 0xe2
					|| data[pos+1] == 0xe3)) {
			return pos;
		}	
		if (pos == 0 && data[pos] == 0x0d && data[pos+1] == 0x0a) {
			return -1; /* Let MAD figure this out */
		}	
		if (pos == 0 && (data[pos] == 'I' && data[pos+1] == 'D' && data[pos+2] == '3')) {
			header_size = (data[pos + 6] << 21) + 
				(data[pos + 7] << 14) +
				(data[pos + 8] << 7) +
				data[pos + 9]; /* syncsafe integer */
			if (data[pos + 5] & 0x10) {
				ext_header = 1;
				header_size += 10; /* 10 byte extended header */
			}
			/* printf("ID3v2.%c detected with header size %d (at pos %d)\n",  0x30 + data[pos + 3], header_size, pos); */
			if (ext_header) {
				/* printf("Extended header detected\n"); */
			}
			header_size += 10;

			if (header_size > STREAM_BUFFER_SIZE) {
				//alsaplayer_error("Header larger than 32K (%d)", header_size);
				return header_size;
			}	
			return header_size;
		} else if (data[pos] == 'R' && data[pos+1] == 'I' &&
				data[pos+2] == 'F' && data[pos+3] == 'F') {
			pos+=4;
			/* alsaplayer_error("Found a RIFF header"); */
			while (pos < size) {
				if (data[pos] == 'd' && data[pos+1] == 'a' &&
						data[pos+2] == 't' && data[pos+3] == 'a') {
					pos += 8; /* skip 'data' and ignore size */
					return pos;
				} else
					pos++;
			}
			puts("MAD debug: invalid header");
			return -1;
		} else if (pos == 0 && data[pos] == 'T' && data[pos+1] == 'A' && 
				data[pos+2] == 'G') {
			return 128;	/* TAG is fixed 128 bytes, we assume! */
		}  else {
			pos++;
		}				
	}
	alsaplayer_error(
			"MAD debug: potential problem file or unhandled info block\n"
			"next 4 bytes =  %x %x %x %x (index = %d, size = %d)\n",
			data[header_size], data[header_size+1],
			data[header_size+2], data[header_size+3],
			(int)header_size, size);
	return -1;
}
Esempio n. 13
0
// Thread which performs an insert to playlist
void insert_looper(void *data) {
	std::set<PlaylistInterface *>::const_iterator i;
	std::set<playlist_interface *>::const_iterator j;

	PlInsertItems * items = (PlInsertItems *)data;
	Playlist *playlist = items->playlist;

	// Stop the list being changed while we add these items
	playlist->Lock();

	// First vetting of the list, and recurse through directories
	std::vector<std::string> vetted_items;
	std::vector<std::string>::const_iterator k = items->items.begin();
	while(k != items->items.end() && playlist->active) {
		additems(&(vetted_items), *k++, MAXRECURSEDEPTH);
	}
	std::vector<PlayItem> newitems;
	if(vetted_items.size() > 0) {
		char cwd[PATH_MAX + 1];
		std::vector<std::string>::const_iterator path;

		if (!getcwd(cwd, PATH_MAX)) {
			alsaplayer_error("Failed to get current working directory");
			cwd[0] = 0;
		}
		// Check items for adding to list
		for(path = vetted_items.begin(); path != vetted_items.end() && playlist->active; path++) {
			// Check that item is valid
			if(!playlist->CanPlay(*path)) {
				//alsaplayer_error("Can't find a player for `%s'\n", path->c_str());
			} else {
				newitems.push_back(PlayItem(*path));
			}
		}
	}
	// Check position is valid
	if(playlist->queue.size() < items->position) {
		items->position = playlist->queue.size();
	}
	// Add to list
	playlist->queue.insert(playlist->queue.begin() + items->position,
						   newitems.begin(),
						   newitems.end());
	if(playlist->curritem > items->position)
		playlist->curritem += newitems.size();

	if(playlist->curritem == 0) {
		playlist->curritem = 1;
	}

	// Tell the subscribing interfaces about the changes
	playlist->LockInterfaces();
	if(playlist->interfaces.size() > 0) {
		for(i = playlist->interfaces.begin();
			i != playlist->interfaces.end(); i++) {
			(*i)->CbInsert(newitems, items->position);
			(*i)->CbSetCurrent(playlist->curritem);
		}
	}
	if (playlist->cinterfaces.size() > 0) {
		for (j = playlist->cinterfaces.begin();
			j != playlist->cinterfaces.end(); j++) {
			(*j)->cbinsert((*j)->data, newitems, items->position);
			(*j)->cbsetcurrent((*j)->data, playlist->curritem);
		}
	}
	playlist->UnlockInterfaces();
	// Free the list again

	/* Metadate gathering is disabled for now. It completely
	 * breaks streaming and it was never very efficient. A complete
	 * reimplementation will follow shortly */
	if (playlist->active)
		info_looper(playlist);

	playlist->Unlock();
	delete items;
}
Esempio n. 14
0
int main(int argc, char **argv)
{
    const char *device_param = default_pcm_device;
    char *prefsdir;
    char thefile[1024];
    char str[1024];
    float start_vol = 1.0;
    int ap_result = 0;
    int use_fragsize = -1; // Initialized
    int use_fragcount = -1; // later
    int do_loopsong = 0;
    int do_looplist = 0;
    int do_enqueue = 0;
    int do_replace = 0;
    int do_realtime = 0;
    int do_remote_control = 0;
    int do_shuffle = 0;
    int do_start = 0;
    int do_stop = 0;
    int do_prev = 0;
    int do_next = 0;
    int do_pause = 0;
    int do_jump = -1;
    int do_clear = 0;
    int do_seek = -1;
    int do_relative = 0;
    int do_setvol = 0;
    int do_quit = 0;
    int do_status = 0;
    int do_speed = 0;
    float speed_val = 0.0;
    int do_onebyone = 0;

    int use_freq = OUTPUT_RATE;
    float use_vol = 1.0;
    int use_session = 0;
    int do_crossfade = 0;
    int do_save = 1;
    int bool_val = 0;
    const char *use_output = NULL;
    char *use_interface = NULL;
    char *use_config = NULL;
    char *use_loopsong = NULL;
    char *use_onebyone = NULL;
    char *use_looplist = NULL;

    int opt;
    int option_index;
    const char *options = "Cc:d:eEf:F:g:hi:J:I:l:n:NMp:qrs:vRSQVxo:";
    struct option long_options[] = {
        /*	{ "long_option", take_argument, 0, 'short_option' }, */
        { "config", 1, 0, 'c' },
        { "device", 1, 0, 'd' },
        { "enqueue", 0, 0, 'e' },
        { "replace", 0, 0, 'E' },
        { "fragsize", 1, 0, 'f' },
        { "frequency", 1, 0, 'F' },
        { "fragcount", 1, 0, 'g' },
        { "help", 0, 0, 'h' },
        { "interface", 1, 0, 'i' },
        { "volume", 1, 0, 'Y' },
        { "session", 1, 0, 'n' },
        { "nosave", 0, 0, 'N' },
        { "path", 1, 0, 'p' },
        { "quiet", 0, 0, 'q' },
        { "realtime", 0, 0, 'r' },
        { "script", 1, 0, 'I'},
        { "session-name", 1, 0, 's' },
        { "version", 0, 0, 'v' },
        { "verbose", 0, 0, 'V' },
        { "reverb", 0, 0, 'R' },
        { "loopsong", 1, 0, 'L' },
        { "looplist", 1, 0, 'P' },
        { "crossfade", 0, 0, 'x' },
        { "output", 1, 0, 'o' },
        { "stop", 0, 0, 'U' },
        { "pause", 0, 0, 'O' },
        { "start", 0, 0, 'T' },
        { "shuffle", 0, 0, 'S' },
        { "prev", 0, 0, 'Q' },
        { "next", 0, 0, 'M' },
        { "jump", 1, 0, 'J' },
        { "seek", 1, 0, 'X' },
        { "relative", 1, 0, 'Z' },
        { "speed", 1, 0, 'H' },
        { "clear", 0, 0, 'C' },
        { "startvolume", 1, 0, 'l' },
        { "quit", 0, 0, 'A' },
        { "status", 0, 0, 'B' },
        { "onebyone", 1, 0, 't' },

        // Options that we want to be able to pass on to gtk_init(). See man
        // gtk-options(7).
        // Give all of these an option number of 128 because we're going to
        // ignore them option switch statement anyway.
        { "gtk-module", 1, 0, 128 },
        { "gtk-debug", 1, 0, 128 },
        { "gtk-no-debug", 1, 0, 128 },
        { "g-fatal-warnings", 0, 0, 128 },

        { "display", 1, 0, 128 },
        { "screen", 1, 0, 128 },
        { "sync", 0, 0, 128 },
        { "no-xshm", 0, 0, 128 },
        { "name", 1, 0, 128 },
        { "class", 1, 0, 128 },
        { "gxid_host", 1, 0, 128 },
        { "gxid_port", 1, 0, 128 },
        { "xim-preedit", 0, 0, 128 },
        { "xim-status", 0, 0, 128 },
        { "gdk-debug", 1, 0, 128 },
        { "gdk-no-debug", 1, 0, 128 },

        // End of list marker.
        { 0, 0, 0, 0 }
    };


    // First setup signal handler
    signal(SIGPIPE, nonfatal_sighandler);   // PIPE (socket control)
    signal(SIGTERM, exit_sighandler);	// kill
    signal(SIGHUP, exit_sighandler);	// kill -HUP / xterm closed
    signal(SIGINT, exit_sighandler);	// Interrupt from keyboard
    signal(SIGQUIT, exit_sighandler);	// Quit from keyboard
    // fatal errors
    signal(SIGBUS, exit_sighandler);	// bus error
    //signal(SIGSEGV, exit_sighandler);	// segfault
    signal(SIGILL, exit_sighandler);	// illegal instruction
    signal(SIGFPE, exit_sighandler);	// floating point exc.
    signal(SIGABRT, exit_sighandler);	// abort()

    // Enable locale support
#ifdef ENABLE_NLS
    setlocale (LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
    bind_textdomain_codeset (PACKAGE, "UTF-8");
#endif

    // Init global mutexes
    pthread_mutex_init(&playlist_sort_seq_mutex, NULL);
#if !defined(EMBEDDED)
    init_effects();
#endif
    while ((opt = getopt_long(argc, argv, options, long_options, &option_index)) != EOF) {
        switch(opt) {
        case 'A':
            do_remote_control = 1;
            do_quit = 1;
            break;
        case 'B':
            do_remote_control = 1;
            do_status = 1;
            break;
        case 'c':
            if (strlen(optarg) < 1023) {
                use_config = optarg;
            } else {
                alsaplayer_error("config file path too long");
                return 1;
            }
            break;
        case 'd':
            device_param = optarg;
            break;
        case 'E':
            do_replace = 1;
        case 'e':
            do_enqueue = 1;
            break;
        case 'f':
            use_fragsize = atoi(optarg);
            if (!use_fragsize) {
                alsaplayer_error("invalid fragment size");
                return 1;
            }
            if (use_fragsize > 32768) {
                alsaplayer_error("fragment size (%d) out of range (0-32768)", use_fragsize);
                return 1;
            }
            break;
        case 'F':
            use_freq = atoi(optarg);
            if (use_freq < 8000 || use_freq > 48000) {
                alsaplayer_error("frequency (%d) out of range (8000-48000)", use_freq);
                return 1;
            }
            break;
        case 'g':
            use_fragcount = atoi(optarg);
            if (use_fragcount < 2 || use_fragcount > 128) {
                alsaplayer_error("fragcount (%d) out of range (2-128)", use_fragcount);
                return 1;
            }
            break;
        case 'h':
            help();
            return 0;
        case 'H':
            if ((sscanf(optarg, "%f", &speed_val))) {
                do_remote_control = 1;
                do_speed = 1;
            }
            break;
        case 'i':
            use_interface = optarg;
            break;
        case 'l':
            start_vol = atof(optarg);
            if (start_vol < 0.0 || start_vol > 1.0) {
                alsaplayer_error("volume (%.3f) out of range: using 1.0", start_vol);
                start_vol = 1.0;
            }
            break;
        case 'L':
            do_remote_control = 1;
            do_loopsong = 1;
            use_loopsong = optarg;
            break;
        case 'Y':
            do_remote_control = 1;
            do_setvol = 1;
            use_vol = atof(optarg);
            if (use_vol < 0.0 || use_vol > 1.0) {
                alsaplayer_error("volume (%.3f) out of range: using 1.0", use_vol);
                use_vol = 1.0;
            }
            break;
        case 'n':
            use_session = atoi(optarg);
            break;
        case 'N':
            do_save = 0;
            break;
        case 'O':
            do_remote_control = 1;
            do_pause = 1;
            break;
        case 'p':
            global_pluginroot = optarg;
            break;
        case 'q':
            global_quiet = 1;
            break;
        case 'r':
            do_realtime = 1;
            break;
        case 's':
            if (strlen(optarg) < 32) {
                global_session_name = strdup(optarg);
            } else {
                alsaplayer_error("max 32 char session name, ignoring");
            }
            break;
        case 'v':
            version();
            return 0;
        case 'V':
            global_verbose = 1;
            break;
        case 'R':
            break;
        case 'P':
            do_remote_control = 1;
            do_looplist = 1;
            use_looplist = optarg;
            break;
        case 'x':
            do_crossfade = 1;
            break;
        case 'o':
            use_output = optarg;
            break;
        case '?':
            return 1;
        case 'I':
            global_interface_script = optarg;
            break;
        case 'U':
            do_remote_control = 1;
            do_stop = 1;
            break;
        case 'T':
            do_remote_control = 1;
            do_start = 1;
            break;
        case 'S':
            do_remote_control = 1;
            do_shuffle = 1;
            break;
        case 'Q':
            do_remote_control = 1;
            do_prev = 1;
            break;
        case 'M':
            do_remote_control = 1;
            do_next = 1;
            break;
        case 'J':
            do_remote_control = 1;
            do_jump = atoi(optarg);
            break;
        case 'C':
            do_remote_control = 1;
            do_clear = 1;
            break;
        case 'X':
            do_remote_control = 1;
            do_seek = atoi(optarg);
            break;
        case 'Z':
            do_remote_control = 1;
            do_relative = 1;
            do_seek = atoi(optarg);
            break;
        case 't':
            do_remote_control = 1;
            do_onebyone = 1;
            use_onebyone = optarg;
            break;
        case 128:
            // Gtk-option which we ignore.
            break;
        default:
            alsaplayer_error("Unknown option '%c'", opt);
            break;
        }
    }

    prefsdir = get_prefsdir();

    mkdir(prefsdir, 0700);	/* XXX We don't do any error checking here */
    snprintf(thefile, sizeof(thefile)-21, "%s/config", prefsdir);
    if (use_config)
        ap_prefs = prefs_load(use_config);
    else
        ap_prefs = prefs_load(thefile);
    if (!ap_prefs) {
        alsaplayer_error("Invalid config file %s\n", use_config ? use_config : thefile);
        return 1;
    }
    /* Initialize some settings (and populate the prefs system if needed */

    if (use_fragsize < 0)
        use_fragsize = prefs_get_int(ap_prefs, "main", "period_size", 4096);
    if (use_fragcount < 0)
        use_fragcount = prefs_get_int(ap_prefs, "main", "period_count", 8);


    if (global_verbose)
        puts(copyright_string);

    if (!global_pluginroot) {
        global_pluginroot = strdup (ADDON_DIR);
    }


    if (use_session == 0) {
        for (; use_session < MAX_REMOTE_SESSIONS+1; use_session++) {
            ap_result = ap_session_running(use_session);

            if (ap_result)
                break;
        }
        if (use_session == (MAX_REMOTE_SESSIONS+1)) {
            //alsaplayer_error("No remote session found");
            if (do_remote_control) {
                alsaplayer_error("No active sessions");
                return 1;
            }
            do_enqueue = 0;
        } else {
            //alsaplayer_error("Found session %d", use_session);
            if (prefs_get_bool(ap_prefs, "main", "multiopen", 1) == 0) {
                // We should not spawn another alsaplayer
                //alsaplayer_error("Using session %d, not doing multiopen", use_session);
                do_enqueue = 1;
                do_replace = 1;
            }
        }
    }

    // Check if we're in remote control mode
    if (do_remote_control) {
        if (do_quit) {
            ap_quit(use_session);
            return 0;
        } else if (do_status) {
            char res[1024];
            float fres;
            int ires;
            fprintf(stdout, "---------------- Session ----------------\n");
            if (ap_get_session_name(use_session, res) && strlen(res))
                fprintf(stdout, "name: %s\n", res);
            if (ap_get_playlist_length(use_session, &ires))
                fprintf(stdout, "playlist_length: %d\n", ires);
            if (ap_get_volume(use_session, &fres))
                fprintf(stdout, "volume: %.2f\n", fres);
            if (ap_get_speed(use_session, &fres))
                fprintf(stdout, "speed: %d%%\n", (int)(fres * 100));
            fprintf(stdout, "-------------- Current Track ------------\n");
            if (ap_get_artist(use_session, res) && strlen(res))
                fprintf(stdout, "artist: %s\n", res);
            if (ap_get_title(use_session, res) && strlen(res))
                fprintf(stdout, "title: %s\n", res);
            if (ap_get_album(use_session, res) && strlen(res))
                fprintf(stdout, "album: %s\n", res);
            if (ap_get_genre(use_session, res) && strlen(res))
                fprintf(stdout, "genre: %s\n", res);
            if (ap_get_file_path(use_session, res) && strlen(res))
                fprintf(stdout, "path: %s\n", res);
            if (ap_get_blocks(use_session, &ires))
                fprintf(stdout, "blocks: %d\n", ires);
            if (ap_get_length(use_session, &ires))
                fprintf(stdout, "length: %d second%s\n", ires, (ires == 1) ? "": "s");
            if (ap_get_position(use_session, &ires))
                fprintf(stdout, "position: %d\n", ires);
            fprintf(stdout, "-----------------------------------------\n");
            return 0;
        } else if (do_setvol) {
            ap_set_volume(use_session, use_vol);
            return 0;
        } else if (do_shuffle) {
            ap_shuffle_playlist(use_session);
            return 0;
        } else if (do_start) {
            ap_play(use_session);
            return 0;
        } else if (do_stop) {
            ap_stop(use_session);
            return 0;
        } else if (do_pause) {
            if (ap_is_paused(use_session, &bool_val)) {
                if (bool_val)
                    ap_unpause(use_session);
                else
                    ap_pause(use_session);
            }
            return 0;
        } else if (do_next) {
            ap_next(use_session);
            return 0;
        } else if (do_prev) {
            ap_prev(use_session);
            return 0;
        } else if (do_jump >= 0) {
            ap_jump_to(use_session, do_jump);
            return 0;
        } else if (do_clear) {
            ap_clear_playlist(use_session);
            return 0;
        } else if (do_relative) {
            if (do_seek != 0)
                ap_set_position_relative(use_session, do_seek);
            return 0;
        } else if (do_speed) {
            if (speed_val < -10.0 || speed_val > 10.0) {
                alsaplayer_error("Speed out of range, must be between -10.00 and 10.00");
                return 1;
            }
            ap_set_speed(use_session, speed_val);
            return 0;
        } else if (do_seek >= 0) {
            ap_set_position(use_session, do_seek);
            return 0;
        } else if (do_loopsong) {
            if (strcasecmp(use_loopsong, "on") != 0) {
                do_loopsong = false;
            }
            ap_set_looping(use_session, do_loopsong);
            return 0;
        } else if (do_onebyone) {
            if (strcasecmp(use_onebyone, "on") != 0) {
                do_onebyone = false;
            }
            ap_set_onebyone(use_session, do_onebyone);
            return 0;
        } else if (do_looplist) {
            if (strcasecmp(use_looplist, "on") != 0) {
                do_looplist = false;
            }
            ap_set_playlist_looping(use_session, do_looplist);
            return 0;
        } else
            alsaplayer_error("No remote control command executed.");
    }


    // Check if we need to enqueue the files
    if (do_enqueue) {
        char queue_name[2048];
        int count = 0;
        int was_playing = 0;
        int playlist_length = 0;

        count = optind;
        ap_result = 1;

        if (do_replace && count < argc) {
            ap_is_playing(use_session, &was_playing);
            if (was_playing) {
                ap_stop(use_session);
            }
            ap_clear_playlist(use_session);
        } else {
            ap_get_playlist_length(use_session, &playlist_length);
            if (!playlist_length) { // Empty list so fire up after add
                was_playing = 1;
            }
        }
        while (count < argc && ap_result) {
            if (is_playlist(argv[count])) {
                ap_add_playlist(use_session, argv[count]);
                count++;
                continue;
            }
            if (argv[count][0] != '/' &&
                    strncmp(argv[count], "http://", 7) != 0 &&
                    strncmp(argv[count], "ftp://", 6) != 0) {
                // Not absolute so append cwd
                if (getcwd(queue_name, 1024) == NULL) {
                    alsaplayer_error("error getting cwd");
                    return 1;
                }
                ap_strlcat(queue_name, "/", sizeof(queue_name));
                ap_strlcat(queue_name, argv[count], sizeof(queue_name));
            } else
                ap_strlcpy(queue_name, argv[count], sizeof(queue_name));
            count++;
            //alsaplayer_error("Adding %s", queue_name);
            ap_result = ap_add_path(use_session, queue_name);
            //alsaplayer_error("ap_result = %d", ap_result);
        }
        if (was_playing)
            ap_jump_to(use_session, 1);
        if (ap_result)
            return 0;
    }

    AlsaNode *node;

    // Check if we want jack
    if (strcmp(argv[0], "jackplayer") == 0) {
        use_output = "jack";
    }

    // Check the output option
    if (use_output == NULL) {
        use_output = prefs_get_string(ap_prefs, "main",
                                      "default_output", "alsa");
    }

    // Else do the usual plugin based thing
    node = new AlsaNode(use_output, device_param, do_realtime);

    if (!node->RegisterPlugin(use_output)) {
        alsaplayer_error("Failed to load output plugin \"%s\". Trying defaults.", use_output);
        if (!node->RegisterPlugin())
            return 1;
    }
    int output_is_ok = 0;
    int output_alternate = 0;

    do {
        if (!node || !node->ReadyToRun()) {
            alsaplayer_error
            ("failed to load output plugin (%s). exitting...",
             use_output ? use_output: "alsa,etc.");
            return 1;
        }
        if (!node->SetSamplingRate(use_freq) ||
                !node->SetStreamBuffers(use_fragsize, use_fragcount, 2)) {
            alsaplayer_error
            ("failed to configure output device...trying OSS");
            /* Special case for OSS, since it's easiest to get going, so try it */
            if (!output_alternate) {
                output_alternate = 1;
                node->RegisterPlugin("oss");
                continue;
            } else {
                return 1;
            }
        }
        output_is_ok = 1;	/* output device initialized */
    } while (!output_is_ok);

    // Initialise reader
    reader_init ();

    // Initialise playlist - must be done before things try to register with it
    playlist = new Playlist(node);

    if (!prefs_get_bool(ap_prefs, "main", "play_on_start", false))
        playlist->Pause();
    else
        playlist->UnPause();

    if (!playlist) {
        alsaplayer_error("Failed to create Playlist object");
        return 1;
    }
    // Add any command line arguments to the playlist
    if (optind < argc) {
        std::vector < std::string > newitems;
        while (optind < argc) {
            if (is_playlist(argv[optind])) {
                if (global_verbose)
                    alsaplayer_error("Loading playlist (%s)", argv[optind]);
                playlist->Load(std::string(argv[optind++]),
                               playlist->Length(), false);
            } else {
                newitems.push_back(std::string(argv[optind++]));
            }
        }
        playlist->Insert(newitems, playlist->Length());
    } else {
        prefsdir = get_prefsdir();
        snprintf(thefile, sizeof(thefile)-28, "%s/alsaplayer.m3u", prefsdir);
        playlist->Load(thefile, playlist->Length(), false);
    }

    // Loop song
    if (do_loopsong) {
        playlist->LoopSong();
    }
    // Loop Playlist
    if (do_looplist) {
        playlist->LoopPlaylist();
    }
    // Play songs one by one
    if (do_onebyone) {
        playlist->SetOneByOne();
    }
    // Cross fading
    if (do_crossfade) {
        playlist->Crossfade();
    }
    // Set start volume
    playlist->GetCorePlayer()->SetVolume(start_vol);


    interface_plugin_info_type interface_plugin_info;
    interface_plugin *ui;

    if (get_interface_from_argv0 (argv[0], str))
        use_interface = str;

    if (use_interface && *use_interface) {
        if (!(interface_plugin_info = load_interface(use_interface))) {
            alsaplayer_error("Failed to load interface %s\n", use_interface);
            goto _fatal_err;
        }
    } else {
        const char *interface = prefs_get_string
                                (ap_prefs, "main", "default_interface", "gtk2");
        // if we're trying to use the old gtk-1 interface, use gtk-2 instead
        if (strcmp (interface, "gtk") == 0)
            interface = "gtk2";
        // if we're trying to use the gtk interface, but we have no
        // $DISPLAY, use the text interface instead
        if (strcmp (interface, "gtk2") == 0 && !getenv("DISPLAY"))
            interface = "text";
        if (!(interface_plugin_info = load_interface(interface))) {
            if (!(interface_plugin_info = load_interface(prefs_get_string
                                          (ap_prefs, "main", "fallback_interface", "text")))) {
                alsaplayer_error("Failed to load text interface. This is bad (%s,%s,%s)",
                                 interface, interface,
                                 global_pluginroot);
                goto _fatal_err;
            }
        }
    }
    if (interface_plugin_info) {
        ui = interface_plugin_info();

        if (global_verbose)
            printf("Interface plugin: %s\n", ui->name);
        if (!ui->init()) {
            alsaplayer_error("Failed to load interface plugin. Should fall back to text\n");
        } else {
            control_socket_start(playlist, ui);
            ui->start(playlist, argc, argv);
            ui->close();
            // Unfortunately gtk+ is a pig when it comes to
            // cleaning up its resources; it doesn't!
            // so we can never safely dlclose gtk+ based
            // user interfaces, bah!
            //dlclose(ui->handle);
            control_socket_stop();
        }
    }
    // Save playlist before exit
    prefsdir = get_prefsdir();
    snprintf(thefile, sizeof(thefile)-25, "%s/alsaplayer", prefsdir);
    playlist->Save(thefile, PL_FORMAT_M3U);

    // Save preferences
    if (ap_prefs && do_save) {
        if (prefs_save(ap_prefs) < 0) {
            alsaplayer_error("failed to save preferences.");
        }
    }

_fatal_err:
    delete playlist;
    //delete p;
    delete node;
    if (global_session_name)
        free(global_session_name);

    return 0;
}
Esempio n. 15
0
prefs_handle_t *prefs_load(const char *filename)
{
	FILE *fd;
	prefs_handle_t *prefs;
	char buf[1024];
	char *val;
	char *key;
	int error_count = 0;

	if (!filename)
		return NULL;

	prefs = malloc(sizeof(prefs_handle_t));

	if (!prefs)
		return NULL;

	memset(prefs, 0, sizeof(prefs_handle_t));

	if ((fd = fopen(filename, "r")) == NULL) {
		if ((fd = fopen(filename, "w")) == NULL) {
			free(prefs);
			return NULL;
		}
	}
	while (fgets(buf, 1023, fd) && error_count < 5) {
		buf[1023] = 0;
		if (strlen(buf) < 1024)
			buf[strlen(buf)-1] = 0; /* get rid of '\n' */
		else {
			error_count++;
			continue;
		}
		if (buf[0] == '#')
			continue;
		if ((val = strchr(buf, '='))) {
			*val = 0; /* replace value separator with 0 */
			val++;
			if ((key = strchr(buf, '.'))) {
				*key = 0; /* replace section separator with 0 */
				key++;
				prefs_set_string(prefs, buf, key, val);
			} else {
				alsaplayer_error("Found old prefs format (%s), ignoring", buf);
				continue;
			}
		} else {
			error_count++;
		}
	}
	fclose(fd);

	if (error_count >= 5) { /* too many errors */
		fprintf(stderr, "*** WARNING: Too many errors in %s\n"
				            "*** WARNING: It is probably corrupted! Please remove it.\n",
					filename);
		return NULL;
	}
	prefs->filename = strdup(filename);

	return prefs;
}
Esempio n. 16
0
static void *
draw_thread_func(void * UNUSED (arg))
{
	Bool configured = FALSE;

	window_w = prefs_get_int(ap_prefs, "opengl_spectrum", "width", DEFAULT_W);
	window_h = prefs_get_int(ap_prefs, "opengl_spectrum", "height", DEFAULT_H);

	if ((window = create_window(window_w, window_h)) == 0)
	{
		alsaplayer_error("unable to create window");
		pthread_exit(NULL);
	}

	XMapWindow(dpy, window);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1, 1, -1, 1, 1.5, 10);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	while(going)
	{
		while(XPending(dpy))
		{
			XEvent event;
			KeySym keysym;
			char buf[16];

			XNextEvent(dpy, &event);
			switch(event.type)
			{
			case ConfigureNotify:
				glViewport(0,0,event.xconfigure.width, event.xconfigure.height);
				window_w = event.xconfigure.width;
				window_h = event.xconfigure.height;
				prefs_set_int(ap_prefs, "opengl_spectrum", "width", window_w);
				prefs_set_int(ap_prefs, "opengl_spectrum", "height", window_h);
				configured = TRUE;
				break;
			case KeyPress:


				XLookupString (&event.xkey, buf, 16, &keysym, NULL);
				switch(keysym)
				{
				case XK_Escape:

					going = FALSE;
					break;
				case XK_z:
					/*xmms_remote_playlist_prev(oglspectrum_vp.xmms_session); */
					break;
				case XK_x:
					/*xmms_remote_play(oglspectrum_vp.xmms_session); */
					break;
				case XK_c:
					/*xmms_remote_pause(oglspectrum_vp.xmms_session); */
					break;
				case XK_v:
					/*xmms_remote_stop(oglspectrum_vp.xmms_session); */
					break;
				case XK_b:
					/* xmms_remote_playlist_next(oglspectrum_vp.xmms_session); */
					break;
				case XK_Up:
					x_speed -= 0.1;
					if(x_speed < -3.0)
						x_speed = -3.0;
					break;
				case XK_Down:
					x_speed += 0.1;
					if(x_speed > 3.0)
						x_speed = 3.0;
					break;
				case XK_Left:
					y_speed -= 0.1;
					if(y_speed < -3.0)
						y_speed = -3.0;

					break;
				case XK_Right:
					y_speed += 0.1;
					if(y_speed > 3.0)
						y_speed = 3.0;
					break;
				case XK_w:
					z_speed -= 0.1;
					if(z_speed < -3.0)
						z_speed = -3.0;
					break;
				case XK_q:
					z_speed += 0.1;
					if(z_speed > 3.0)
						z_speed = 3.0;
					break;
				case XK_Return:
					x_speed = 0.0;
					y_speed = 0.5;
					z_speed = 0.0;
					x_angle = 20.0;
					y_angle = 45.0;
					z_angle = 0.0;
					break;
				}

				break;
			case ClientMessage:
				if ((Atom)event.xclient.data.l[0] == wm_delete_window_atom)
				{
					going = FALSE;
				}
				break;
			}
		}
		if(configured)
		{
			x_angle += x_speed;
			if(x_angle >= 360.0)
				x_angle -= 360.0;

			y_angle += y_speed;
			if(y_angle >= 360.0)
				y_angle -= 360.0;

			z_angle += z_speed;
			if(z_angle >= 360.0)
				z_angle -= 360.0;

			draw_bars();
		}
	}

	if (glxcontext)
	{
		glXMakeCurrent(dpy, 0, NULL);
		glXDestroyContext(dpy, glxcontext);
		glxcontext = NULL;
	}
	if (window)
	{
		if (grabbed_pointer)
		{
			XUngrabPointer(dpy, CurrentTime);
			grabbed_pointer = FALSE;
		}

		XDestroyWindow(dpy, window);
		window = 0;
	}
	pthread_mutex_unlock(&scope_mutex);
	stop_display(0); /* Close down display */
	pthread_exit(NULL);
}
Esempio n. 17
0
static int mad_play_frame(input_object *obj, char *buf)
{
	struct mad_local_data *data;
	struct mad_pcm *pcm;
	mad_fixed_t const *left_ch;
	mad_fixed_t const *right_ch;
	int16_t	*output;
	int nsamples;
	int nchannels;

	if (!obj)
		return 0;
	data = (struct mad_local_data *)obj->local_data;
	if (!data)
		return 0;
	if (data->bytes_avail < 3072) {
		/*
		   alsaplayer_error("Filling buffer = %d,%d",
		   data->bytes_avail,
		   data->map_offset + MAD_BUFSIZE - data->bytes_avail);
		   */
		fill_buffer(data, -1); /* data->map_offset + MAD_BUFSIZE - data->bytes_avail); */
		mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
	} else {
		/* alsaplayer_error("bytes_avail = %d", data->bytes_avail); */
	}
	if (mad_frame_decode(&data->frame, &data->stream) == -1) {
		if (!MAD_RECOVERABLE(data->stream.error)) {
			/*
			   alsaplayer_error("MAD error: %s (%d). fatal", 
			   error_str(data->stream.error, data->str),
			   data->bytes_avail);
			   */	
			mad_frame_mute(&data->frame);
			return 0;
		} else {
			if (reader_eof(data->mad_fd)) {
				return 0;
			}	
			//alsaplayer_error("MAD error: %s (not fatal)", error_str(data->stream.error, data->str)); 
			memset(buf, 0, obj->frame_size);
			return 1;
		}
	}
	data->current_frame++;
	if (data->seekable && data->current_frame < (obj->nr_frames + FRAME_RESERVE)) {
		data->frames[data->current_frame] = 
			data->map_offset + data->stream.this_frame - data->mad_map;
		if (data->current_frame > 3 && 
				(data->frames[data->current_frame] -
				 data->frames[data->current_frame-3]) < 6) {
			return 0;
		}		
		if (data->highest_frame < data->current_frame)
			data->highest_frame = data->current_frame;
	}				

	mad_synth_frame (&data->synth, &data->frame);

	{
		pcm = &data->synth.pcm;
		output = (int16_t *)buf;
		nsamples = pcm->length;
		nchannels = pcm->channels;
		if (nchannels != obj->nr_channels) {
			alsaplayer_error("ERROR: bad data stream! (channels: %d != %d, frame %d)",
					nchannels, 
					obj->nr_channels,
					data->current_frame);
			mad_frame_mute(&data->frame);
			memset(buf, 0, obj->frame_size);
			return 1;
		}	
		obj->nr_channels = nchannels;
		if (data->samplerate != data->frame.header.samplerate) {
			alsaplayer_error("ERROR: bad data stream! (samplerate: %d != %d, frame %d)",
					data->samplerate, 
					data->frame.header.samplerate,
					data->current_frame);
			mad_frame_mute(&data->frame);
			memset(buf, 0, obj->frame_size);
			return 1;
		}	
		data->samplerate = data->frame.header.samplerate;
		left_ch = pcm->samples[0];
		right_ch = pcm->samples[1];
		while (nsamples--) {
			*output++ = my_scale(*(left_ch++));
			if (nchannels == 1) {
				*output++ = my_scale(*(left_ch-1));
			} else { /* nchannels == 2 */
				*output++ = my_scale(*(right_ch++));
			}	

		}
	}
	data->bytes_avail = data->stream.bufend - data->stream.next_frame;
	return 1;
}
Esempio n. 18
0
void playlist_looper(void *data)
{
#ifdef DEBUG
	printf("THREAD-%d=playlist thread\n", getpid());
#endif /* DEBUG */
	Playlist *pl = (Playlist *)data;
	CorePlayer *coreplayer;
	if(!pl) return;

	while(pl->active) {
		if (!pl->IsPaused()) {
			if (!(coreplayer = (CorePlayer *)(pl->coreplayer)))
				return;

			if (!coreplayer->IsActive()) {
				if (pl->Length()) {
					if (pl->LoopingSong()) {
						pl->Play(pl->GetCurrent());
					} else {
						pl->Next();
						if(pl->IsOneByOne()) {
							pl->Stop();
						}
					}
					// TODO? set a flag to skip the dosleep()
				}
			}

			if (pl->Crossfading() && pl->Length() && pl->coreplayer->GetSpeed() >= 0.0) {
				// Cross example
				// Calc the block to sec value
				int nr_blocks = coreplayer->GetBlocks();
				int totaltime = coreplayer->GetCurrentTime(nr_blocks);

				float blocktime = (float)totaltime  / (float)nr_blocks;
				float xstart = 300; // 3.0 seconds
				float xblock = xstart / blocktime;
				//alsaplayer_error("xblock = %.2f", xblock);
				if ((coreplayer->GetBlocks() - coreplayer->GetPosition()) < (int)xblock) {
						if (pl->player1->IsActive() && pl->player2->IsActive()) {
							alsaplayer_error("Stopping players in playlist_looper");
							pl->player1->Stop();
							pl->player2->Stop();
						}
						if (pl->player1->IsActive()) {
								pl->player2->SetSpeed(pl->coreplayer->GetSpeed());
								pl->coreplayer = pl->player2;
						} else {
								pl->player1->SetSpeed(pl->coreplayer->GetSpeed());
								pl->coreplayer = pl->player1;
						}
						pl->Next();
						// TODO? set a flag to skip the dosleep()
				}
			}
		}
		// Update the position: notifier information
		pl->coreplayer->PositionUpdate();
		dosleep(200000);
	}
}
Esempio n. 19
0
/* follow redirect URLs if encountered                                 */
static int reconnect (http_desc_t *desc, char *redirect)
{
    char request [2048];
    char response [10240];
    char *s;
    int error;
    socklen_t error_len;
    struct hostent *hp;
    struct sockaddr_in address;
    fd_set set;
    struct timeval tv;
    int flags;
    int rc = 0;

    /* Clear error status */
    desc->error = 0;

    /* Stop filling thread */
    if (desc->going) {
	desc->going = 0;
	desc->dont_wait = 10;
	pthread_cond_signal (&desc->dont_wait_signal);
	pthread_join (desc->buffer_thread, NULL);
    }

    /* Close connection */
    if (desc->sock) {
	close (desc->sock);
	desc->sock = 0;
    }

    /* Free buffer */
    if (desc->buffer) {
	free (desc->buffer);
	desc->buffer = NULL;
    }
    desc->begin = 0;
    desc->len = 0;

    /* Look up for host IP */
    if (!(hp = gethostbyname (desc->host))) {
	alsaplayer_error ("HTTP: Couldn't look up host %s.", desc->host);
	return 1;
    }

    /* Open socket */
    desc->sock = socket (AF_INET, SOCK_STREAM, 0);
    if (desc->sock==-1) {
	alsaplayer_error ("HTTP: Couldn't open socket.");
	return 1;
    }

    flags = fcntl (desc->sock, F_GETFL, 0);
    fcntl (desc->sock, F_SETFL, flags | O_NONBLOCK);

    /* Fill address struct */
    address.sin_family = AF_INET;
    address.sin_port = htons (desc->port);
    memcpy (&address.sin_addr.s_addr, *(hp->h_addr_list), sizeof (address.sin_addr.s_addr));

    /* Start connection */
    if (connect (desc->sock, (struct sockaddr *) &address, sizeof (struct sockaddr_in)) == -1) {
	if (errno != EINPROGRESS) {
	    alsaplayer_error ("HTTP: Couldn't connect to host %s:%u", desc->host, desc->port);
	    return 1;
	}
    }

    /* Wait for connection */
    tv.tv_sec = 10;
    tv.tv_usec = 0;
    FD_ZERO (&set);
    FD_SET (desc->sock, &set);

    if (select (desc->sock+1, NULL, &set, NULL, &tv) < 1) {
	alsaplayer_error ("HTTP: Connection is too slow.");
	return 1;
    }

    /* Test for errors while connected */
    error_len = sizeof (error);
    getsockopt (desc->sock, SOL_SOCKET, SO_ERROR, &error, &error_len);
    if (error) {
	alsaplayer_error ("HTTP: Couldn't connect to host %s:%u", desc->host, desc->port);
	return 1;
    }

    /* Send request for remote file */
    snprintf (request, 2048, "GET %s HTTP/1.1\r\n"
			     "Host: %s\r\n"
			     "Connection: close\r\n"
			     "User-Agent: %s/%s\r\n"
			     "Range: bytes=%ld-\r\n"
			     "Icy-Metadata: 1\r\n"
			     "\r\n",
			     desc->path, desc->host, PACKAGE, VERSION,
			     desc->pos);
    //alsaplayer_error("%s", request);
    write (desc->sock, request, strlen (request));
    desc->begin = desc->buffer_pos = desc->pos;

    /* Get response */
    if (get_response_head (desc->sock, response, 10240))
	return 1;

    /* Check protocol */
    if (!strncmp (response, "HTTP/1.0 ", 9)) {
	desc->seekable = 0;
    } else if (!strncmp (response, "HTTP/1.1 ", 9)) {
        desc->seekable = 1;
    } else if (!strncmp (response, "ICY 200 OK", 10)) {
    	desc->seekable = 0;
	rc = 200;
	//alsaplayer_error("%s", response);
    } else if (!strncmp (response, "ICY 400 Server Full", 19)) {
	rc = 400;
    } else if (!strncmp (response, "ICY 404", 7)) {
	 rc = 404;
    } else {
	if (strlen(response)) {
		alsaplayer_error ("HTTP: Wrong server protocol for http://%s:%u%s",
			desc->host, desc->port, desc->path);
		alsaplayer_error("ERROR:\n\"%s\"", response);
	}
	return 1;
    }

    /* Check return code */
    if (strstr(response, "HTTP"))
    	rc = atoi (response + 9);

    if (rc != 200 && rc != 206) {
	/* Wrong code */
	if (rc == 404) {
	    /* 404 */
	    alsaplayer_error ("HTTP: File not found: http://%s:%u%s",
		desc->host, desc->port, desc->path);
	    return 1;
	} else if (rc == 302) {
            s = strstr(response, "302");
	    if (s) {
		    //alsaplayer_error("%s", s);
		    s = strstr(response, "Location: ");
		    if (s && redirect) {
			    /* Parse redirect */
			    if (sscanf(s, "Location: %[^\r]", redirect)) {
				    /* alsaplayer_error("Redirection: %s", redirect); */
			    }
		    }
		    return 1;
	    }
	} else if (rc == 400) {
		if (desc->status) {
			desc->status(desc->data, "Server is full");
		}
		if (redirect)
			redirect[0] = 0;
		return 1;
	} else if (rc == 401) {
		if (desc->status) {
			desc->status(desc->data, "Unauthorized access");
		}
		if (redirect)
			redirect[0] = 0;
		return 1;
	} else if (rc == 404) {
		if (desc->status) {
			desc->status(desc->data, "Resource not found");
		}
		if (redirect)
			redirect[0] = 0;
		return 1;
	} else {
		/* unknown */
		alsaplayer_error ("HTTP: We don't support %d response code: http://%s:%u%s",
				rc, desc->host, desc->port, desc->path);
		if (redirect)
			redirect[0] = 0;
		return 1;
	}
    }
    /* Looking for size */
    s = strstr (response, "\r\nContent-Length: ");
    if (s) {
	/* Set size only once */
	if (!desc->size)
	    desc->size = atol (s+18);
    } else {
	desc->seekable = 0;
    }
    /* Look for icy-metaint */
    s = strstr (response, "\r\nicy-metaint:");
    if (s) {
	desc->icy_metaint = atoi(s+14);
	//alsaplayer_error("Found metaint: %d", desc->icy_metaint);
    } else {
    	desc->icy_metaint = 0;
    }

    /* Setup played parts */
    desc->played_parts = desc->seekable ? 5 : 0;

    /* Attach thread to fill a buffer */
    desc->going = 1;
    pthread_create (&desc->buffer_thread, NULL, (void* (*)(void *)) buffer_thread, desc);

    return 0;
} /* end of: reconnect */
Esempio n. 20
0
/* Trying to fill info from id3 tagged file */
static void parse_id3 (const char *path, stream_info *info)
{
	void *fd;
	unsigned char buf [2024];
	unsigned char g;

	/* Open stream */
	fd = reader_open (path, NULL, NULL);
	if (!fd)  return;

	/* --------------------------------------------------- */
	/* Trying to load id3v2 tags                           */
	if (reader_read (buf, 10, fd) != 10) {
		reader_close (fd);
		return;
	}

	if (memcmp(buf, "ID3", 3) == 0) {
		/* Parse id3v2 tags */

		/* Header */
		unsigned char major_version = buf [3];
		int f_unsynchronization = buf [5] & (1<<7);
		int f_extended_header = buf [5] & (1<<6);
		int f_experimental = buf [5] & (1<<5);
		int header_size = from_synchsafe4 (buf + 6);
		int name_size = buf [3] == 2 ? 3 : 4;
		int ext_size = 0;
		
		if (f_extended_header) {
//			alsaplayer_error ("FIXME: Extended header found in mp3."
//					"Please contact alsaplayer team.\n"
//					"Filename: %s", path);
	//		reader_close (fd);
	//		return;
			ext_size = 1;	//stupid but should do
		}

		if (f_unsynchronization) {
			alsaplayer_error ("FIXME: f_unsynchronization is set."
					"Please contact alsaplayer team.\n"
					"Filename: %s", path);
			reader_close (fd);
			return;
		}

		if (f_experimental) {
			alsaplayer_error ("FIXME: f_experimental is set."
					"Please contact alsaplayer team.\n"
					"Filename: %s", path);
			reader_close (fd);
			return;
		}

			if (ext_size) {
				char b[4];
				if (reader_read (b, 4, fd) != 4) {
						reader_close(fd);
						return;
				}
				if (major_version == 2)
					ext_size = from_synchsafe3 (b);
				else
					ext_size = from_synchsafe4 (b);
				
				if (reader_seek (fd, ext_size - 4, SEEK_CUR) < 0) {
					reader_close (fd);
					return;
				}
			
			}
			
		/* -- -- read frames -- -- */
		while (reader_tell (fd) <= header_size + 10) {
			unsigned int size;
			
			
			/* Get name of this frame */
			if (reader_read (buf, name_size, fd) != (unsigned)name_size) {
				reader_close (fd);
				return;
			}

			if (buf [0] == '\0')  break;
			if (buf [0] < 'A')  break;
			if (buf [0] > 'Z')  break;

			/* Get size */
			if (major_version == 2) {
				char sb [3];

				if (reader_read (sb, 3, fd) != 3) {
					reader_close (fd);
					return;
				}

				size = from_synchsafe3 (sb);
			} else {
				char sb [4];

				if (reader_read (sb, 4, fd) != 4) {
					reader_close (fd);
					return;
				}

				size = from_synchsafe4 (sb);
			}

			/* skip frame flags */
//			if (reader_seek (fd, 1, SEEK_CUR) == -1) {
//				reader_close (fd);
//				return;
//			}

			int start = 0;		
			// read them
			char b[2];
			if (reader_read (b, 2, fd) != 2) {
				reader_close (fd);
				return;
			} else {
			
				if (b[1] & (1 << 6)) {
//					printf ("Grouping added\n");
					start++;
				}
				if (b[1] & (1 << 3)) {
//					printf ("Compression added\n");
				}
				if (b[1] & (1 << 2)) {
//					printf ("Encryption added\n");
				}
				if (b[1] & (1 << 1)) {
//					printf ("Unsynch added\n");
				}
				if (b[1] & (1 << 0)) {
//					printf ("Length added\n");
					start+=4;
				}	
			}
				
				
				
				if (size>=1024) {
				/* I will not support such long tags...
				 * Only if someone ask for it...
				 * not now... */

				if (reader_seek (fd, size, SEEK_CUR) == -1) {
					reader_close (fd);
					return;
				}

				continue;
			}


			/* read info */
			if (reader_read (buf + name_size, size, fd) != size) {
				reader_close (fd);
				return;
			}

			/* !!! Ok. There we have frame name and data. */
			/* Lets use it. */
			if (name_size == 4) {
				if (memcmp (buf, "TIT2", 4)==0)
					fill_from_id3v2 (info->title, buf + name_size + start,
							sizeof (info->title), size - start);
				else if (memcmp (buf, "TPE1", 4)==0)
					fill_from_id3v2 (info->artist, buf + name_size + start,
							sizeof (info->artist), size - start);
				else if (memcmp (buf, "TALB", 4)==0)
					fill_from_id3v2 (info->album, buf + name_size + start,
							sizeof (info->album), size - start);
				else if (memcmp (buf, "TYER", 4)==0)
					fill_from_id3v2 (info->year, buf + name_size + start,
							sizeof (info->year), size - start);
				else if (memcmp (buf, "COMM", 4)==0)
					fill_from_id3v2 (info->comment, buf + name_size + start,
							sizeof (info->comment), size - start);
				else if (memcmp (buf, "TRCK", 4)==0)
					fill_from_id3v2 (info->track, buf + name_size + start,
							sizeof (info->track), size - start);
				else if (memcmp (buf, "TCON", 4)==0) {
					/* Genre */
					/* TODO: Optimize duplicated code */
					unsigned int gindex;

					if (sscanf (buf + name_size + start +1, "(%u)", &gindex)==1) {
						if (gindex==255)
							*info->genre = '\0';
						else if (sizeof (genres)/sizeof(char*) <= gindex)
							snprintf (info->genre, sizeof (info->genre), "(%u)", gindex);
						else
							snprintf (info->genre, sizeof (info->genre), "%s", genres[gindex]);
					} else
						fill_from_id3v2 (info->genre, buf + name_size + start,
								sizeof (info->genre), size - start);
				}
			} /* end of 'if name_size == 4' */

		} /* end of frames read */

		/* end parsing */
		reader_close (fd);
		return;
	} /* end of id3v2 parsing */

	/* --------------------------------------------------- */
	/* Trying to load id3v1 tags                           */
	if (reader_seek (fd, -128, SEEK_END) == -1) {
		reader_close (fd);
		return;
	}

	if (reader_read (buf, 128, fd) != 128) {
		reader_close (fd);
		return;
	}

	if (memcmp(buf, "TAG", 3) == 0) {
		/* ID3v1 frame found */

		/* title */
		strncpy (info->title, buf + 3, 30);
		rstrip (info->title);

		/* artist */
		strncpy (info->artist, buf + 33, 30);
		rstrip (info->artist);

		/* album */
		strncpy (info->album, buf + 63, 30);
		rstrip (info->album);

		/* year */
		strncpy (info->year, buf + 93, 4);
		rstrip (info->year);

		/* comment */
		strncpy (info->comment, buf + 97, 28);
		rstrip (info->comment);

		/* track number */
		if (buf [125] == '\0')
			snprintf (info->track, sizeof (info->track), "%u", buf [126]);

		/* genre */
		g = buf [127];
		if (g==255)
			*info->genre = '\0';
		else if (sizeof (genres)/sizeof(char*) <= g)
			snprintf (info->genre, sizeof (info->genre), "(%u)", g);
		else
			snprintf (info->genre, sizeof (info->genre), "%s", genres[g]);
	} /* end of id3v1 parsing */

	reader_close (fd);
}
Esempio n. 21
0
/* Buffer filling thread.                                              */
static void buffer_thread (http_desc_t *desc)
{
    pthread_mutex_t mut;			/* Temporary mutex. */
    int BLOCK_SIZE = HTTP_BLOCK_SIZE;
    void *ibuffer;
    int rest = 0;
    int metasize = 0, metapos = 0, extra_read = 0;
    char *p;

    /* Init */
    pthread_mutex_init (&mut, NULL);

    if (desc->icy_metaint) {
	BLOCK_SIZE = (HTTP_BLOCK_SIZE > desc->icy_metaint) ? desc->icy_metaint : HTTP_BLOCK_SIZE;
    }

    ibuffer = malloc (BLOCK_SIZE << 1);

    /* Process while main thread allow it. */
    while (desc->going) {
	void *newbuf;
	int readed;

#ifdef DEBUG_HTTP_BUFFERING
	print_debug_info (desc);
#endif

	rest = metasize = 0;

	/* trying to shrink buffer */
	pthread_mutex_lock (&desc->buffer_lock);
	shrink_buffer (desc);
	pthread_mutex_unlock (&desc->buffer_lock);

	/* let them know about our state, heh */
	status_notify (desc);

	/* check for overflow */
	if (desc->len > http_buffer_size) {
	    /* Notice waiting function that the new block of data has arrived */
	    desc->new_datablock = 1;
	    pthread_cond_signal (&desc->new_datablock_signal);

	    /* Make pause */
	    if (!desc->dont_wait) {
		pthread_mutex_lock (&mut);
		cond_timedwait_relative (&desc->dont_wait_signal, &mut, calc_time_to_wait (desc));
		pthread_mutex_unlock (&mut);
	    } else {
		desc->dont_wait--;
	    }

	    continue;
	}

	/* read to internal buffer */
        readed = read_data (desc->sock, ibuffer, BLOCK_SIZE);

	/* reasons to stop */
	if (readed == 0) {
	    desc->going = 0;
	} else if (readed <0) {
	    desc->error = 1;
	    desc->going = 0;
	} else {
	    /* Something readed */

	    /* Metadata stuff */
	    if (desc->icy_metaint > 0 &&
		(desc->buffer_pos+readed) >  desc->icy_metaint) {
		/* Metadata block is next! */
		rest = (desc->buffer_pos+readed) - desc->icy_metaint;

		p = ((char *)ibuffer);
		p += (readed-rest);
		metapos = (readed-rest);
		if (rest) {
		    metasize = *(int8_t *)p;
		    metasize <<= 4;
		    if (rest < metasize) {
			/* Uh oh, big trouble ahead, or maybe not? */
			extra_read = read_data (desc->sock, ibuffer+readed, metasize);
			readed += extra_read;
			rest += extra_read;
		    }
		    if (metasize > 4080) {
			alsaplayer_error("Invalid metasize (%d)", metasize);
		    } else if (metasize > 0) {
			p++;
			p[metasize] = '\0';
			pthread_mutex_lock (&desc->meta_lock);
			if (desc->metadata) {
			    free(desc->metadata);
			}
			desc->metadata = malloc(strlen(p)+1);
			memcpy(desc->metadata, p, strlen(p));
			pthread_mutex_unlock (&desc->meta_lock);
		    } else {
			/* Metadata is zero length */
		    }
		} else {
		    alsaplayer_error("Rest = 0???");
		}
		metasize++; /* Length byte */
	    } else {
		desc->buffer_pos += readed;
	    }

            /* These operations are fast. -> doesn't break reader_read */
	    /* ---------------- lock buffer ( */
	    pthread_mutex_lock (&desc->buffer_lock);

	    /* enlarge buffer */
	    newbuf = malloc (desc->len + (BLOCK_SIZE * 2)); /* HTTP_BLOCK_SIZE */
	    memcpy (newbuf, desc->buffer, desc->len);
	    if (metasize) {
		    memcpy(newbuf + desc->len, ibuffer, metapos);
		    memcpy(newbuf + desc->len + metapos, ibuffer+metapos+metasize, rest - metasize);
		    readed -= metasize;
		    desc->buffer_pos = rest - metasize;
	    } else {
		    memcpy (newbuf + desc->len, ibuffer, readed);
	    }
	    /* switch buffers */
	    free (desc->buffer);
	    desc->buffer = newbuf;
	    desc->len += readed;

	    /* unlock buffer ) */
	    pthread_mutex_unlock (&desc->buffer_lock);
	}

	/* Notice waiting function that the new block of data has arrived */
	desc->new_datablock = 1;
	pthread_cond_signal (&desc->new_datablock_signal);

	/* Do wait */
	if (desc->going && !desc->dont_wait) {
	    pthread_mutex_lock (&mut);
	    cond_timedwait_relative (&desc->dont_wait_signal, &mut, calc_time_to_wait (desc));
	    pthread_mutex_unlock (&mut);
	}

	if (desc->dont_wait)
	    desc->dont_wait--;
    }

    free (ibuffer);
    pthread_exit (NULL);
} /* end of: buffer_thread */
Esempio n. 22
0
static int mad_open(input_object *obj, const char *path)
{
	struct mad_local_data *data;
	char *p;
	int mode;

	if (!obj)
		return 0;

	obj->local_data = malloc(sizeof(struct mad_local_data));
	if (!obj->local_data) {
		puts("failed to allocate local data");
		return 0;
	}
	data = (struct mad_local_data *)obj->local_data;
	memset(data, 0, sizeof(struct mad_local_data));

	if ((data->mad_fd = reader_open(path, &reader_status, obj)) == NULL) {
		fprintf(stderr, "mad_open(obj, %s) failed\n", path);
		free(obj->local_data);
		obj->local_data = NULL;
		return 0;
	}
	obj->flags = 0;

	if (strncasecmp(path, "http://", 7) == 0) {
		obj->flags |= P_STREAMBASED;
		strcpy(data->sinfo.status, "Prebuffering");
	} else {
		obj->flags |= P_FILEBASED;
	}
	if (!reader_seekable(data->mad_fd)) {
		data->seekable = 0;
	} else {
		obj->flags |= P_SEEK;
		obj->flags |= P_PERFECTSEEK;
		data->seekable = 1;
	}
	obj->flags |= P_REENTRANT;

	mad_init_decoder(data);
	memset(&data->xing, 0, sizeof(struct xing));
	xing_init (&data->xing);
	data->mad_init = 1;
	fill_buffer(data, -1);
	//alsaplayer_error("initial bytes_avail = %d", data->bytes_avail);
	if (obj->flags & P_PERFECTSEEK) {
		data->offset = find_initial_frame(data->mad_map, 
				data->bytes_avail < STREAM_BUFFER_SIZE ? data->bytes_avail :
				STREAM_BUFFER_SIZE);
	} else {
		data->offset = 0;
	}	
	data->highest_frame = 0;
	if (data->offset < 0) {
		//fprintf(stderr, "mad_open() couldn't find valid MPEG header\n");
		data->offset = 0;
	}
	//alsaplayer_error("data->offset = %d", data->offset);
	if (data->offset > data->bytes_avail) {
		data->seekable = 1;
		//alsaplayer_error("Need to refill buffer (data->offset = %d)", data->offset);
		fill_buffer(data, 0);
		mad_stream_buffer(&data->stream, data->mad_map, data->bytes_avail);
	} else {
		mad_stream_buffer(&data->stream, data->mad_map + data->offset,
				data->bytes_avail - data->offset);
		data->bytes_avail -= data->offset;
	}	
first_frame:

	if ((mad_header_decode(&data->frame.header, &data->stream) == -1)) {
		switch (data->stream.error) {
			case MAD_ERROR_BUFLEN:
				return 0;
			case MAD_ERROR_LOSTSYNC:
			case MAD_ERROR_BADEMPHASIS:
			case MAD_ERROR_BADBITRATE:
			case MAD_ERROR_BADLAYER:	
			case MAD_ERROR_BADSAMPLERATE:	
				//alsaplayer_error("Error %x (frame %d)", data->stream.error, data->current_frame);
				data->bytes_avail-=(data->stream.next_frame - data->stream.this_frame);
				goto first_frame;
				break;
			case MAD_ERROR_BADBITALLOC:
				return 0;
			case MAD_ERROR_BADCRC:
				alsaplayer_error("MAD_ERROR_BADCRC: %s", error_str(data->stream.error, data->str));
			case MAD_ERROR_BADBIGVALUES:
			case MAD_ERROR_BADDATAPTR:
				break;
			default:
				alsaplayer_error("ERROR: %s", error_str(data->stream.error, data->str));
				alsaplayer_error("No valid frame found at start (pos: %d, error: 0x%x --> %x %x %x %x) (%s)", data->offset, data->stream.error, 
						data->stream.this_frame[0],
						data->stream.this_frame[1],
						data->stream.this_frame[2],
						data->stream.this_frame[3],path);
				return 0;
		}
	}

	mad_frame_decode(&data->frame, &data->stream);
	/*	
		alsaplayer_error("xing parsing...%x %x %x %x (%x %d)", 
		data->stream.this_frame[0], data->stream.this_frame[1],
		data->stream.this_frame[2], data->stream.this_frame[3],
		data->stream.anc_ptr, data->stream.anc_bitlen);
		*/		
	if (xing_parse(&data->xing, data->stream.anc_ptr, data->stream.anc_bitlen) == 0) {
		// We use the xing data later on
	}

	mode = (data->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ?
		1 : 2;
	data->samplerate = data->frame.header.samplerate;
	data->bitrate	= data->frame.header.bitrate;
	mad_synth_frame (&data->synth, &data->frame);
	{
		struct mad_pcm *pcm = &data->synth.pcm;			

		obj->nr_channels = pcm->channels;
		//alsaplayer_error("nr_channels = %d", obj->nr_channels);
	}
	//alsaplayer_error("Initial: %d, %d, %d", data->samplerate, data->bitrate, obj->nr_channels);
	/* Calculate some values */
	data->bytes_avail = data->stream.bufend - data->stream.next_frame;
	{
		int64_t time;
		int64_t samples;
		int64_t frames;

		long oldpos = reader_tell(data->mad_fd);
		reader_seek(data->mad_fd, 0, SEEK_END);

		data->filesize = reader_tell(data->mad_fd);
		data->filesize -= data->offset;

		reader_seek(data->mad_fd, oldpos, SEEK_SET);
		if (data->bitrate)
			time = (data->filesize * 8) / (data->bitrate);
		else
			time = 0;

		samples = 32 * MAD_NSBSAMPLES(&data->frame.header);

		obj->frame_size = (int) samples << 2; /* Assume 16-bit stereo */
		frames = data->samplerate * (time+1) / samples;
		if (data->xing.flags & XING_FRAMES) {
			obj->nr_frames = data->xing.frames;
		} else {	
			obj->nr_frames = (int) frames;
		}	
		obj->nr_tracks = 1;
	}
	/* Determine if nr_frames makes sense */
	if (!(obj->flags & P_SEEK) && (obj->flags & P_STREAMBASED)) {
		obj->nr_frames = -1;
	}	

	/* Allocate frame index */
	if (!data->seekable  || obj->nr_frames > 1000000 ||
			(data->frames = (ssize_t *)malloc((obj->nr_frames + FRAME_RESERVE) * sizeof(ssize_t))) == NULL) {
		data->seekable = 0; // Given really
	}	else {
		data->seekable = 1;
		data->frames[0] = 0;
	}	
	data->mad_init = 1;

	p = strrchr(path, '/');
	if (p) {
		strcpy(data->filename, ++p);
	} else {
		strcpy(data->filename, path);
	}
	strcpy(data->path, path);

	data->parse_id3 = prefs_get_bool(ap_prefs, "mad", "parse_id3", 1);

	return 1;
}
Esempio n. 23
0
void nonfatal_sighandler(int x)
{
    alsaplayer_error("Warning: alsaplayer interrupted by signal %d", x);
}
Esempio n. 24
0
static int
flac_open (input_object * obj, const char * name)
{
    if (!obj)
	return 0;
    if (!name)
	return 0;

    reader_type * rdr = reader_open (name, NULL, NULL);
    if (!rdr)
    {
	alsaplayer_error ("flac_open: reader_open failed");
	return 0;
    }

    obj->flags = 0;
    Flac::FlacStream * f = 0;
    try
    {
	if (Flac::FlacStream::isFlacStream (name))
	{
	    if (reader_seekable (rdr))
	    {
		f = new Flac::FlacSeekableStream (name, rdr);
		obj->flags |= P_SEEK | P_PERFECTSEEK;
	    }
	    else
		f = new Flac::FlacStream (name, rdr);
	}
#ifdef HAVE_LIBOGGFLC
	else
	{
	    f = new Flac::OggFlacStream (name, rdr);
	}
#endif
    }
    catch (...)
    {
	alsaplayer_error ("flac_open: unable to allocate memory for plugin.");
	delete f;
	reader_close (rdr);
	return 0;
    }

    if (f && f->open ())
    {
	obj->block_size  = f->engine ()->apBlockSize ();

	// attach a song info tag

	if (Flac::FlacTag::hasTag (f->name ()))
	{
	    Flac::FlacTag * t = Flac::FlacTag::newTag (f->name ());
	    f->setTag (t);
	}

	if (strncasecmp (name, "http://", 7) == 0)
	    obj->flags |= P_STREAMBASED;
	else
	    obj->flags |= P_FILEBASED;
	obj->nr_channels  = f->engine ()->apChannels ();
	obj->flags       |= P_REENTRANT;
	obj->nr_blocks    = f->engine ()->apBlocks ();
	obj->nr_tracks    = 1;
	obj->ready        = 1;
	obj->local_data   = (void *) f;
	return 1;
    }
    else
    {
	alsaplayer_error ("flac_open: unable to open flac stream or "
			  "unsupported flac stream (%s)", name);
	delete f;
	obj->block_size  = 0;
	obj->nr_channels = 0;
	obj->flags       = 0;
	obj->nr_blocks   = 0;
	obj->nr_tracks   = 0;
	obj->ready       = 0;
	obj->local_data  = 0;
	return 0;
    }
}