⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sequencer.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 3 页
字号:
					int val = w14 & 0x7f;					int i, key;					if (p1 < 64)	/* Combine MSB and LSB */					{						val = ((synth_devs[dev]->							chn_info[chn].controllers[p1 & ~32] & 0x7f) << 7)							| (synth_devs[dev]->							chn_info[chn].controllers[p1 | 32] & 0x7f);						p1 &= ~32;					}					/* Handle all playing notes on this channel */					key = ((int) chn << 8);					for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)						if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)							synth_devs[dev]->controller(dev, i, p1, val);				}				else					synth_devs[dev]->controller(dev, chn, p1, w14);			}			else	/* Mode 1 */				synth_devs[dev]->controller(dev, chn, p1, w14);			break;		case MIDI_PITCH_BEND:			if (seq_mode == SEQ_2)			{				synth_devs[dev]->chn_info[chn].bender_value = w14;				if ((int) dev < num_synths)				{					/* Handle all playing notes on this channel */					int i, key;					key = (chn << 8);					for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)						if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)							synth_devs[dev]->bender(dev, i, w14);				}				else					synth_devs[dev]->bender(dev, chn, w14);			}			else	/* MODE 1 */				synth_devs[dev]->bender(dev, chn, w14);			break;		default:;	}}static int seq_timing_event(unsigned char *event_rec){	unsigned char cmd = event_rec[1];	unsigned int parm = *(int *) &event_rec[4];	if (seq_mode == SEQ_2)	{		int ret;		if ((ret = tmr->event(tmr_no, event_rec)) == TIMER_ARMED)			if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)				wake_up(&seq_sleeper);		return ret;	}	switch (cmd)	{		case TMR_WAIT_REL:			parm += prev_event_time;			/*			 * NOTE!  No break here. Execution of TMR_WAIT_REL continues in the			 * next case (TMR_WAIT_ABS)			 */		case TMR_WAIT_ABS:			if (parm > 0)			{				long time;				time = parm;				prev_event_time = time;				seq_playing = 1;				request_sound_timer(time);				if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)					wake_up(&seq_sleeper);				return TIMER_ARMED;			}			break;		case TMR_START:			seq_time = jiffies;			prev_input_time = 0;			prev_event_time = 0;			break;		case TMR_STOP:			break;		case TMR_CONTINUE:			break;		case TMR_TEMPO:			break;		case TMR_ECHO:			if (seq_mode == SEQ_2)				seq_copy_to_input(event_rec, 8);			else			{				parm = (parm << 8 | SEQ_ECHO);				seq_copy_to_input((unsigned char *) &parm, 4);			}			break;		default:;	}	return TIMER_NOT_ARMED;}static void seq_local_event(unsigned char *event_rec){	unsigned char   cmd = event_rec[1];	unsigned int    parm = *((unsigned int *) &event_rec[4]);	switch (cmd)	{		case LOCL_STARTAUDIO:			DMAbuf_start_devices(parm);			break;		default:;	}}static void seq_sysex_message(unsigned char *event_rec){	int dev = event_rec[1];	int i, l = 0;	unsigned char  *buf = &event_rec[2];	if ((int) dev > max_synthdev)		return;	if (!(synth_open_mask & (1 << dev)))		return;	if (!synth_devs[dev])		return;	l = 0;	for (i = 0; i < 6 && buf[i] != 0xff; i++)		l = i + 1;	if (!synth_devs[dev]->send_sysex)		return;	if (l > 0)		synth_devs[dev]->send_sysex(dev, buf, l);}static int play_event(unsigned char *q){	/*	 * NOTE! This routine returns	 *   0 = normal event played.	 *   1 = Timer armed. Suspend playback until timer callback.	 *   2 = MIDI output buffer full. Restore queue and suspend until timer	 */	unsigned int *delay;	switch (q[0])	{		case SEQ_NOTEOFF:			if (synth_open_mask & (1 << 0))				if (synth_devs[0])					synth_devs[0]->kill_note(0, q[1], 255, q[3]);			break;		case SEQ_NOTEON:			if (q[4] < 128 || q[4] == 255)				if (synth_open_mask & (1 << 0))					if (synth_devs[0])						synth_devs[0]->start_note(0, q[1], q[2], q[3]);			break;		case SEQ_WAIT:			delay = (unsigned int *) q;	/*							 * Bytes 1 to 3 are containing the *							 * delay in 'ticks'							 */			*delay = (*delay >> 8) & 0xffffff;			if (*delay > 0)			{				long time;				seq_playing = 1;				time = *delay;				prev_event_time = time;				request_sound_timer(time);				if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)					wake_up(&seq_sleeper);				/*				 * The timer is now active and will reinvoke this function				 * after the timer expires. Return to the caller now.				 */				return 1;			}			break;		case SEQ_PGMCHANGE:			if (synth_open_mask & (1 << 0))				if (synth_devs[0])					synth_devs[0]->set_instr(0, q[1], q[2]);			break;		case SEQ_SYNCTIMER: 	/*					 * Reset timer					 */			seq_time = jiffies;			prev_input_time = 0;			prev_event_time = 0;			break;		case SEQ_MIDIPUTC:	/*					 * Put a midi character					 */			if (midi_opened[q[2]])			{				int dev;				dev = q[2];				if (dev < 0 || dev >= num_midis || midi_devs[dev] == NULL)					break;				if (!midi_devs[dev]->outputc(dev, q[1]))				{					/*					 * Output FIFO is full. Wait one timer cycle and try again.					 */					seq_playing = 1;					request_sound_timer(-1);					return 2;				}				else					midi_written[dev] = 1;			}			break;		case SEQ_ECHO:			seq_copy_to_input(q, 4);	/*							 * Echo back to the process							 */			break;		case SEQ_PRIVATE:			if ((int) q[1] < max_synthdev)				synth_devs[q[1]]->hw_control(q[1], q);			break;		case SEQ_EXTENDED:			extended_event(q);			break;		case EV_CHN_VOICE:			seq_chn_voice_event(q);			break;		case EV_CHN_COMMON:			seq_chn_common_event(q);			break;		case EV_TIMING:			if (seq_timing_event(q) == TIMER_ARMED)			{				return 1;			}			break;		case EV_SEQ_LOCAL:			seq_local_event(q);			break;		case EV_SYSEX:			seq_sysex_message(q);			break;		default:;	}	return 0;}static void seq_startplay(void){	unsigned long flags;	int this_one, action;	while (qlen > 0)	{		save_flags(flags);		cli();		qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;		qlen--;		restore_flags(flags);		seq_playing = 1;		if ((action = play_event(&queue[this_one * EV_SZ])))		{		/* Suspend playback. Next timer routine invokes this routine again */			if (action == 2)			{				qlen++;				qhead = this_one;			}			return;		}	}	seq_playing = 0;	if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)		wake_up(&seq_sleeper);}static void reset_controllers(int dev, unsigned char *controller, int update_dev){	int i;	for (i = 0; i < 128; i++)		controller[i] = ctrl_def_values[i];}static void setup_mode2(void){	int dev;	max_synthdev = num_synths;	for (dev = 0; dev < num_midis; dev++)	{		if (midi_devs[dev] && midi_devs[dev]->converter != NULL)		{			synth_devs[max_synthdev++] = midi_devs[dev]->converter;		}	}	for (dev = 0; dev < max_synthdev; dev++)	{		int chn;		synth_devs[dev]->sysex_ptr = 0;		synth_devs[dev]->emulation = 0;		for (chn = 0; chn < 16; chn++)		{			synth_devs[dev]->chn_info[chn].pgm_num = 0;			reset_controllers(dev,				synth_devs[dev]->chn_info[chn].controllers,0);			synth_devs[dev]->chn_info[chn].bender_value = (1 << 7);	/* Neutral */			synth_devs[dev]->chn_info[chn].bender_range = 200;		}	}	max_mididev = 0;	seq_mode = SEQ_2;}int sequencer_open(int dev, struct file *file){	int retval, mode, i;	int level, tmp;	unsigned long flags;	if (!sequencer_ok)		sequencer_init();	level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;	dev = dev >> 4;	mode = translate_mode(file);	DEB(printk("sequencer_open(dev=%d)\n", dev));	if (!sequencer_ok)	{/*		printk("Sound card: sequencer not initialized\n");*/		return -ENXIO;	}	if (dev)		/* Patch manager device (obsolete) */		return -ENXIO;	if(synth_devs[dev] == NULL)		request_module("synth0");	if (mode == OPEN_READ)	{		if (!num_midis)		{			/*printk("Sequencer: No MIDI devices. Input not possible\n");*/			sequencer_busy = 0;			return -ENXIO;		}	}	save_flags(flags);	cli();	if (sequencer_busy)	{		restore_flags(flags);		return -EBUSY;	}	sequencer_busy = 1;	obsolete_api_used = 0;	restore_flags(flags);	max_mididev = num_midis;	max_synthdev = num_synths;	pre_event_timeout = MAX_SCHEDULE_TIMEOUT;	seq_mode = SEQ_1;	if (pending_timer != -1)	{		tmr_no = pending_timer;		pending_timer = -1;	}	if (tmr_no == -1)	/* Not selected yet */	{		int i, best;		best = -1;		for (i = 0; i < num_sound_timers; i++)			if (sound_timer_devs[i] && sound_timer_devs[i]->priority > best)			{				tmr_no = i;				best = sound_timer_devs[i]->priority;			}		if (tmr_no == -1)	/* Should not be */			tmr_no = 0;	}	tmr = sound_timer_devs[tmr_no];	if (level == 2)	{		if (tmr == NULL)		{			/*printk("sequencer: No timer for level 2\n");*/			sequencer_busy = 0;			return -ENXIO;		}		setup_mode2();	}	if (!max_synthdev && !max_mididev)	{		sequencer_busy=0;		return -ENXIO;	}	synth_open_mask = 0;	for (i = 0; i < max_mididev; i++)	{		midi_opened[i] = 0;		midi_written[i] = 0;	}	for (i = 0; i < max_synthdev; i++)	{		if (synth_devs[i]==NULL)			continue;		if (synth_devs[i]->owner)			__MOD_INC_USE_COUNT (synth_devs[i]->owner);		if ((tmp = synth_devs[i]->open(i, mode)) < 0)		{			printk(KERN_WARNING "Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);			if (synth_devs[i]->midi_dev)				printk(KERN_WARNING "(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);		}		else		{			synth_open_mask |= (1 << i);			if (synth_devs[i]->midi_dev)				midi_opened[synth_devs[i]->midi_dev] = 1;		}	}	seq_time = jiffies;	prev_input_time = 0;	prev_event_time = 0;	if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))	{		/*		 * Initialize midi input devices		 */		for (i = 0; i < max_mididev; i++)			if (!midi_opened[i] && midi_devs[i])			{				if (midi_devs[i]->owner)					__MOD_INC_USE_COUNT (midi_devs[i]->owner);					if ((retval = midi_devs[i]->open(i, mode,					sequencer_midi_input, sequencer_midi_output)) >= 0)				{					midi_opened[i] = 1;				}			}	}	if (seq_mode == SEQ_2) {		if (tmr->owner)			__MOD_INC_USE_COUNT (tmr->owner);		tmr->open(tmr_no, seq_mode);	} 	init_waitqueue_head(&seq_sleeper); 	init_waitqueue_head(&midi_sleeper);	output_threshold = SEQ_MAX_QUEUE / 2;	return 0;}void seq_drain_midi_queues(void){	int i, n;	/*	 * Give the Midi drivers time to drain their output queues	 */	n = 1;	while (!signal_pending(current) && n)	{		n = 0;		for (i = 0; i < max_mididev; i++)			if (midi_opened[i] && midi_written[i])				if (midi_devs[i]->buffer_status != NULL)					if (midi_devs[i]->buffer_status(i))						n++;		/*		 * Let's have a delay		 */ 		if (n) 			interruptible_sleep_on_timeout(&seq_sleeper,						       HZ/10);	}}void sequencer_release(int dev, struct file *file){	int i;	int mode = translate_mode(file);	dev = dev >> 4;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -