| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -38,10 +38,10 @@ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int  config_max_level = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int  config_min_level = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static unsigned long long current_usecs () { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static unsigned long long current_cycles () { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				unsigned long long now; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				rdtscll (now); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return now / 450; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return now; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static void | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -275,17 +275,17 @@ alsa_driver_configure_stream (alsa_driver_t *driver, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if ((err = snd_pcm_sw_params_set_stop_threshold (handle, sw_params, ~0U)) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: cannot set start mode for %s", stream_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: cannot set stop mode for %s", stream_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if ((err = snd_pcm_sw_params_set_silence_threshold (handle, sw_params, 0)) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: cannot set start mode for %s", stream_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: cannot set silence threshold for %s", stream_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if ((err = snd_pcm_sw_params_set_silence_size (handle, sw_params, driver->frames_per_cycle * driver->nfragments)) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: cannot set start mode for %s", stream_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: cannot set silence size for %s", stream_name); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -605,8 +605,10 @@ alsa_driver_audio_start (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				snd_pcm_poll_descriptors (driver->playback_handle, &driver->pfd, 1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->pfd.events = POLLOUT | POLLERR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->playback_nfds = snd_pcm_poll_descriptors_count (driver->playback_handle); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->capture_nfds = snd_pcm_poll_descriptors_count (driver->capture_handle); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->pfd = (struct pollfd *) malloc (sizeof (struct pollfd) *  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					(driver->playback_nfds + driver->capture_nfds)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -689,6 +691,7 @@ alsa_driver_set_clock_sync_status (alsa_driver_t *driver, channel_t chn, ClockSy | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int under_gdb = FALSE; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static unsigned long long last_time; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static int | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			alsa_driver_wait (alsa_driver_t *driver) | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -704,34 +707,106 @@ alsa_driver_wait (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				channel_t chn; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				GSList *node; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				sample_t *buffer; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//	unsigned long long end; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int need_capture = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int need_playback = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				int i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				unsigned long long before; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			  again: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (poll (&driver->pfd, 1, 1000) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (errno == EINTR) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						printf ("poll interrupt\n"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				while (need_playback || need_capture) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					int p_timed_out, c_timed_out; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					int ci; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					int nfds; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					nfds = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (need_playback) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						snd_pcm_poll_descriptors (driver->playback_handle, &driver->pfd[0], driver->playback_nfds); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						nfds += driver->playback_nfds; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (need_capture) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						snd_pcm_poll_descriptors (driver->capture_handle, &driver->pfd[nfds], driver->capture_nfds); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						ci = nfds; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						nfds += driver->capture_nfds; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					/* ALSA doesn't set POLLERR in some versions of 0.9.X */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					for (i = 0; i < nfds; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						driver->pfd[nfds].events |= POLLERR; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//		printf ("c? %d p? %d poll on %d fds\n", need_capture, need_playback, nfds); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					before = current_cycles(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (poll (driver->pfd, nfds, 1000) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (errno == EINTR) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							printf ("poll interrupt\n"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// this happens mostly when run | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							// under gdb, or when exiting due to a signal | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (under_gdb) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							goto again; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (under_gdb) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								goto again; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							return 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						jack_error ("ALSA::Device: poll call failed (%s)", strerror (errno)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA::Device: poll call failed (%s)", strerror (errno)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->time_at_interrupt = current_usecs(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (driver->pfd.revents & POLLERR) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: poll reports error."); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (driver->pfd.revents == 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					// timed out, such as when the device is paused | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					return 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					driver->time_at_interrupt = current_cycles(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//		printf ("time in poll: %f usecs since last = %f usecs\n",  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//			((float) (driver->time_at_interrupt - before)/450.0f), | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//			((float) (driver->time_at_interrupt - last_time)/450.0f)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//		last_time = driver->time_at_interrupt; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					p_timed_out = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (need_playback) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						for (i = 0; i < driver->playback_nfds; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (driver->pfd[i].revents & POLLERR) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								jack_error ("ALSA: poll reports error on playback stream."); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (driver->pfd[i].revents == 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								p_timed_out++; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (p_timed_out == 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							need_playback = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					c_timed_out = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (need_capture) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						for (i = ci; i < nfds; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (driver->pfd[i].revents & POLLERR) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								jack_error ("ALSA: poll reports error on capture stream."); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							if (driver->pfd[i].revents == 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
								c_timed_out++; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						if (c_timed_out == 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
							need_capture = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					if (p_timed_out == driver->playback_nfds && c_timed_out == driver->capture_nfds) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						jack_error ("ALSA: poll time out"); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
						return -1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					}		 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				xrun_detected = FALSE; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -766,7 +841,7 @@ alsa_driver_wait (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				   periods. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				*/ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				avail = (avail / driver->frames_per_cycle) * driver->frames_per_cycle; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				avail = avail - (avail % driver->frames_per_cycle); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				while (avail) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
	
		
			
				| 
				
				
				
					
				
				 | 
			
			 | 
			@@ -783,6 +858,8 @@ alsa_driver_wait (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					contiguous = capture_avail < playback_avail ? capture_avail : playback_avail; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//		printf ("\tcontiguous = %lu\n", contiguous); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					/* XXX possible race condition here with silence_pending */ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					/* XXX this design is wrong. cf. ardour/audioengine *** FIX ME *** */ | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -852,7 +929,7 @@ alsa_driver_wait (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					avail -= contiguous; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//	end = current_usecs(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//	end = current_cycles(); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			//	printf ("entire cycle took %f usecs\n", ((float)(end - driver->time_at_interrupt))/450.0f); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return 0; | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1058,7 +1135,7 @@ alsa_driver_set_hw_monitoring (alsa_driver_t *driver, int yn) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static nframes_t | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			alsa_driver_frames_since_cycle_start (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return (nframes_t) ((driver->frame_rate / 1000000.0) * ((float) (current_usecs() - driver->time_at_interrupt))); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				return (nframes_t) ((driver->frame_rate / 1000000.0) * ((float) (current_cycles() - driver->time_at_interrupt))); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			static ClockSyncStatus | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1101,6 +1178,10 @@ alsa_driver_delete (alsa_driver_t *driver) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					snd_pcm_sw_params_free (driver->playback_sw_params); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					driver->playback_sw_params = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (driver->pfd) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					free (driver->pfd); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if (driver->hw) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					driver->hw->release (driver->hw); | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1164,6 +1245,10 @@ alsa_driver_new (char *name, char *alsa_device, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->capture_ports = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->playback_ports = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->pfd = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->playback_nfds = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				driver->capture_nfds = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
				if ((err = snd_pcm_open (&driver->playback_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
					jack_error ("ALSA: Cannot open PCM device %s/%s", name, alsa_device); | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |