Skip to content
Snippets Groups Projects
channel.c 85 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    	if (len > sizeof(ts->data) / 2 - 1) {
    		ast_log(LOG_WARNING, "Can't generate that much data!\n");
    		return -1;
    	}
    	memset(&ts->f, 0, sizeof(ts->f));
    	for (x=0;x<len/2;x++) {
    		ts->data[x] = ts->vol * (
    				sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
    				sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
    			);
    	}
    	ts->f.frametype = AST_FRAME_VOICE;
    	ts->f.subclass = AST_FORMAT_SLINEAR;
    	ts->f.datalen = len;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ts->f.samples = samples;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	ts->f.offset = AST_FRIENDLY_OFFSET;
    	ts->f.data = ts->data;
    	ast_write(chan, &ts->f);
    	ts->pos += x;
    	if (ts->duration > 0) {
    		if (ts->pos >= ts->duration * 8)
    			return -1;
    	}
    	return 0;
    }
    
    static struct ast_generator tonepair = {
    	alloc: tonepair_alloc,
    	release: tonepair_release,
    	generate: tonepair_generator,
    };
    
    int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
    {
    	struct tonepair_def d = { 0, };
    	d.freq1 = freq1;
    	d.freq2 = freq2;
    	d.duration = duration;
    	if (vol < 1)
    		d.vol = 8192;
    	else
    		d.vol = vol;
    	if (ast_activate_generator(chan, &tonepair, &d))
    		return -1;
    	return 0;
    }
    
    void ast_tonepair_stop(struct ast_channel *chan)
    {
    	ast_deactivate_generator(chan);
    }
    
    int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
    {
    	struct ast_frame *f;
    	int res;
    	if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
    		return res;
    
    	/* Give us some wiggle room */
    	while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
    		f = ast_read(chan);
    		if (f)
    			ast_frfree(f);
    		else
    			return -1;
    	}
    	return 0;
    }
    
    ast_group_t ast_get_group(char *s)
    
    {
    	char *copy;
    	char *piece;
    	char *c=NULL;
    	int start=0, finish=0,x;
    
    	ast_group_t group = 0;
    
    	copy = ast_strdupa(s);
    	if (!copy) {
    		ast_log(LOG_ERROR, "Out of memory\n");
    		return 0;
    	}
    	c = copy;
    	
    	while((piece = strsep(&c, ","))) {
    		if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
    			/* Range */
    		} else if (sscanf(piece, "%d", &start)) {
    			/* Just one */
    			finish = start;
    		} else {
    
    			ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.\n", s, piece);
    			continue;
    
    		}
    		for (x=start;x<=finish;x++) {
    
    			if ((x > 63) || (x < 0)) {
    				ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
    
    
    static int (*ast_moh_start_ptr)(struct ast_channel *, char *) = NULL;
    static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
    
    static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
    
    
    
    void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, char *),
    
    								 void (*stop_ptr)(struct ast_channel *),
    								 void (*cleanup_ptr)(struct ast_channel *)
    								 ) 
    
    {
    	ast_moh_start_ptr = start_ptr;
    	ast_moh_stop_ptr = stop_ptr;
    
    }
    
    void ast_uninstall_music_functions(void) 
    {
    	ast_moh_start_ptr = NULL;
    	ast_moh_stop_ptr = NULL;
    
    }
    
    /*! Turn on/off music on hold on a given channel */
    
    int ast_moh_start(struct ast_channel *chan, char *mclass) 
    {
    	if(ast_moh_start_ptr)
    		return ast_moh_start_ptr(chan, mclass);
    
    	if (option_verbose > 2)
    		ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default");
    	
    	return 0;
    }
    
    void ast_moh_stop(struct ast_channel *chan) 
    {
    	if(ast_moh_stop_ptr)
    		ast_moh_stop_ptr(chan);
    }
    
    
    void ast_moh_cleanup(struct ast_channel *chan) 
    {
    	if(ast_moh_cleanup_ptr)
            ast_moh_cleanup_ptr(chan);
    }
    
    
    void ast_channels_init(void)
    {
    	ast_cli_register(&cli_show_channeltypes);
    }
    
    
    /*--- ast_print_group: Print call group and pickup group ---*/
    char *ast_print_group(char *buf, int buflen, ast_group_t group) 
    {
    	unsigned int i;
    	int first=1;
    	char num[3];
    
    	buf[0] = '\0';
    	
    	if (!group)	/* Return empty string if no group */
    		return(buf);
    
    	for (i=0; i<=63; i++) {	/* Max group is 63 */
    		if (group & (1 << i)) {
    	   		if (!first) {
    				strncat(buf, ", ", buflen);
    			} else {
    				first=0;
    	  		}
    			snprintf(num, sizeof(num), "%u", i);
    			strncat(buf, num, buflen);
    		}
    	}
    	return(buf);
    }