fine sample rate control for RME hdsp 9632

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

  I've added a control to the hdsp driver to control the dds register on the 9632. This allows fine tuning of the sample rate as is supported by the windows driver. The feature is implemented as an offset to the current sample rate, since most of the code assumes only discrete sample rates are supported. So the sample rate will always be selected and indicated as one of the standard supported sample rates but may actually be a few % higher or lower. It seems to work very well.

One possible application is to discipline the sample rate from the system clock or a GPS receiver to provide a long term accurate precise frequency source without expensive reference clocks.

The patch is against alsa-driver-1.0.14rc3

Julian

 


Now you can scan emails quickly with a reading pane. Get the new Yahoo! Mail.
277a278,282
> /* RME says n = 104857600000000, but in the windows MADI driver, I see:
> 	return 104857600000000 / rate; // 100 MHz
> 	return 110100480000000 / rate; // 105 MHz
> */	   
> #define DDS_NUMERATOR 104857600000000ULL;  /*  =  2^20 * 10^8 */
1004,1008c1009
< 	/* RME says n = 104857600000000, but in the windows MADI driver, I see:
< //	return 104857600000000 / rate; // 100 MHz
< 	return 110100480000000 / rate; // 105 MHz
<         */	   
< 	n = 104857600000000ULL;  /*  =  2^20 * 10^8 */
---
> 	n = DDS_NUMERATOR;
3087a3089,3159
> #define HDSP_DDS_OFFSET(xname, xindex) \
> { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
>   .name = xname, \
>   .index = xindex, \
>   .info = snd_hdsp_info_dds_offset, \
>   .get = snd_hdsp_get_dds_offset, \
>   .put = snd_hdsp_put_dds_offset \
> }
> 
> static int hdsp_dds_offset(struct hdsp *hdsp)
> {
> 	u64 n;
> 	u32 r;
> 	unsigned int dds_value = hdsp->dds_value;
> 	int system_sample_rate = hdsp->system_sample_rate;
> 
> 	n = DDS_NUMERATOR;
> 	/*
> 	 * dds_value = n / rate
> 	 * rate = n / dds_value
> 	 */
> 	div64_32(&n, dds_value, &r);
> 	if (system_sample_rate >= 112000)
> 		n *= 4;
> 	else if (system_sample_rate >= 56000)
> 		n *= 2;
> 	return ((int)n) - system_sample_rate;
> }
> 
> static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
> {
> 	int rate = hdsp->system_sample_rate + offset_hz;
> 	hdsp_set_dds_value(hdsp, rate);
> 	return 0;
> }
> 
> static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
> {
> 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
> 	uinfo->count = 1;
> 	uinfo->value.integer.min = -5000;
> 	uinfo->value.integer.max = 5000;
> 	return 0;
> }
> 
> static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
> {
> 	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
> 	
> 	ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
> 	return 0;
> }
> 
> static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
> {
> 	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
> 	int change;
> 	int val;
> 	
> 	if (!snd_hdsp_use_is_exclusive(hdsp))
> 		return -EBUSY;
> 	val = ucontrol->value.enumerated.item[0];
> 	spin_lock_irq(&hdsp->lock);
> 	if (val != hdsp_dds_offset(hdsp))
> 		change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
> 	else
> 		change = 0;
> 	spin_unlock_irq(&hdsp->lock);
> 	return change;
> }
> 
3092c3164,3165
< HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
---
> HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0),
> HDSP_DDS_OFFSET("DDS Sample Rate Offset (Hz)", 0)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux