usb声卡 订阅
USB声卡是通过USB总线与计算机系统连接的声卡,常见的样式有便于使用的U盘形状和摆放于桌面的盒式形状,还可以集成在耳机、功放内部。 [1-2]  USB声卡可以为计算机系统提供比集成声卡更好的音频录制、回放质量,还可以为计算机扩展出多声道音频输出输入接口、MIDI接口、XLR接口、光纤接口等。 [1] 展开全文
USB声卡是通过USB总线与计算机系统连接的声卡,常见的样式有便于使用的U盘形状和摆放于桌面的盒式形状,还可以集成在耳机、功放内部。 [1-2]  USB声卡可以为计算机系统提供比集成声卡更好的音频录制、回放质量,还可以为计算机扩展出多声道音频输出输入接口、MIDI接口、XLR接口、光纤接口等。 [1]
信息
外文名
USB sound card
类    型
计算机外设
中文名
USB声卡
接    口
USB
usb声卡声卡简介
USB声卡是外置声卡。它的USB联线有四股正在使用,其中两股用来从主机上获得电能,而另外两股则是信息数据线。 USB声卡是走USB总线.板载声卡是走PCI总线。USB声卡和音质未必挂钩,既有地摊级音质和价格的产品,也有适用于专业音频制作的产品。
收起全文
精华内容
下载资源
问答
  • usb声卡 源码

    2017-01-17 14:40:57
    usb声卡 原理图 PCB
  • USB声卡驱动.rar

    2021-03-08 23:42:10
    USB声卡驱动.rar
  • usb声卡驱动(六) 前面记录了usb声卡驱动的注册过程。 下面,查看usb声卡里面pcm的打开和关闭,都做了什么工作。 一点基础前提 因为本系列文章的核心是,usb声卡驱动。所以并不会深入到alsa内部的细节。但是在进行...

    usb声卡驱动(六)

    前面记录了usb声卡驱动的注册过程。

    下面,查看usb声卡里面pcm的打开和关闭,都做了什么工作。

    一点基础前提

    因为本系列文章的核心是,usb声卡驱动。所以并不会深入到alsa内部的细节。但是在进行pcm的打开和关闭之前。需要知道一些alsa内部的一些东西。

    在《usb声卡驱动(四)》和《usb声卡驱动(五)》中提到了一个函数:

    int snd_card_register(struct snd_card * card);
    

    该函数,需要知道如下的一个简单逻辑。

    1. 它遍历所有的component,比如前面提到的pcm
    2. 然后调用这些component的dev_register回调。
    3. 在这些回调中,会有各个component专用的一些设置。比如调用device_create创建对应的驱动文件等。这样应用就可以通过文件系统来使用它了。

    好了,仅仅知道这些就可以了。下面,看看pcm的打开。

    pcm的打开

    在《usb声卡驱动(四)》中,提及到,每个pcm可以有多个substream.而每次open时,就是open一个substream出来。而substream的个数,由下面函数的第四,第五参数指定。

    int snd_pcm_new(struct snd_card * card, const char * id, int device, int playback_count, int capture_count, struct snd_pcm ** rpcm)
    

    当有多个substream时,每次open,就打开一个substream,在使用过程中,通过substream的index来区分

    当只有一个substream时,第一次open,就打开一个substream。如果重复打开,则依赖文件是否要阻塞,如果阻塞,则open调用不会返回。如果非阻塞,则返回一个错误值。

    在usb声卡驱动中,只有一个substream,想一想为什么?

    代码如下(详情见《usb声卡驱动(五)》):

    //啦啦啦,终于找到,我们信息苦苦期待的创建pcm对象啦
    	err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
    			  stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
    			  stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
    			  &pcm);
    

    对于usb声卡驱动而言,在open时,substream直接由参数,传递进来。那么substrea是什么时候创建的呢?

    因为本笔记不是对alsa的解析,所以只给出alsa内部的简单逻辑,等有空了,再来详细记录一下alsa内部的世界吧。

    1. 当调用snd_pcm_new函数创建pcm实例时,内部还会根据传递的playback(capture)的个数,来创建对应个数的substream。
    2. 这些substream通过内部的next,形成一个链表
    3. 同一个方向(playback或者capture)的substream。由一个包装类snd_pcm_str包装。因此,会有两个包装类(playback或者capture),他们组成一个snd_pcm_str的数组。
    4. pcm实例(一个特殊的component)持有上面的snd_pcm_str数组。
    5. 当需要open的时候,则分配一个已经创建好的substream即可。

    alsa针对pcm的open的内部逻辑,几乎就变成了上面的逆序了。简述如下:

    1. 首先得到pcm实例,和方向信息
    2. 根据方向信息,从snd_pcm_str的数组中,选择对应的snd_pcm_str对象。
    3. 从snd_pcm_str对象的substream获取substream的链表。然后判断合适的substream返回即可。
    4. 调用这个substream的open回调,即《usb声卡驱动(五)》中谈到的snd_usb_playback_ops或者snd_usb_capture_ops中的open回调

    接下来,就是snd_usb_playback_ops或者snd_usb_capture_ops中的open回调了.从《usb声卡驱动(四)》可以知道,这个open回调里面,几乎就是对runtime对象的hw字段进行初始化。

    如下:

    static int snd_usb_playback_open(struct snd_pcm_substream *substream)
    {
    	return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
    }
    
    static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
    {
    	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
    	struct snd_pcm_runtime *runtime = substream->runtime;
    	struct snd_usb_substream *subs = &as->substream[direction];
    
    	subs->interface = -1;
    	subs->altset_idx = 0;
    	//预定义好的硬件描述
    	runtime->hw = snd_usb_hardware;
    	runtime->private_data = subs;
    	subs->pcm_substream = substream;
    	/* runtime PM is also done there */
    
    	/* initialize DSD/DOP context */
    	subs->dsd_dop.byte_idx = 0;
    	subs->dsd_dop.channel = 0;
    	subs->dsd_dop.marker = 1;
    
    	return setup_hw_info(runtime, subs);
    }
    

    注意,上面的hw赋值,snd_usb_hardware的值如下:

    static struct snd_pcm_hardware snd_usb_hardware =
    {
    	//表示硬件支持的功能和特性
    	.info =			SNDRV_PCM_INFO_MMAP |
    				SNDRV_PCM_INFO_MMAP_VALID |
    				SNDRV_PCM_INFO_BATCH |
    				SNDRV_PCM_INFO_INTERLEAVED |
    				SNDRV_PCM_INFO_BLOCK_TRANSFER |
    				SNDRV_PCM_INFO_PAUSE,
    	//最大buffer
    	.buffer_bytes_max =	1024 * 1024,
    	//最小period
    	.period_bytes_min =	64,
    	//最大period
    	.period_bytes_max =	512 * 1024,
    	//最小/大period数
    	.periods_min =		2,
    	.periods_max =		1024,
    };
    

    这个结构体,表示的是usb声卡支持的硬件功能和特性。

    上面的函数内容,没有什么可以赘述的,进入setup_hw_info函数,如下:

    
    static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
    {
    	struct audioformat *fp;
    	unsigned int pt, ptmin;
    	int param_period_time_if_needed;
    	int err;
    
    	//赋值格式
    	runtime->hw.formats = subs->formats;
    	
    	//初始化各种值
    	runtime->hw.rate_min = 0x7fffffff;
    	runtime->hw.rate_max = 0;
    	runtime->hw.channels_min = 256;
    	runtime->hw.channels_max = 0;
    	runtime->hw.rates = 0;
    	ptmin = UINT_MAX;
    	/* check min/max rates and channels */
    	//检查各种最小和最大值
    	list_for_each_entry(fp, &subs->fmt_list, list) {
    		runtime->hw.rates |= fp->rates;
    		if (runtime->hw.rate_min > fp->rate_min)
    			runtime->hw.rate_min = fp->rate_min;
    		if (runtime->hw.rate_max < fp->rate_max)
    			runtime->hw.rate_max = fp->rate_max;
    		if (runtime->hw.channels_min > fp->channels)
    			runtime->hw.channels_min = fp->channels;
    		if (runtime->hw.channels_max < fp->channels)
    			runtime->hw.channels_max = fp->channels;
    		if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
    			/* FIXME: there might be more than one audio formats... */
    			runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
    				fp->frame_size;
    		}
    		pt = 125 * (1 << fp->datainterval);//计算出来的周期间隔,单位微妙
    		ptmin = min(ptmin, pt);
    	}
    	//电源管理相关,暂时跳过
    	err = snd_usb_autoresume(subs->stream->chip);
    	if (err < 0)
    		return err;
    
    
    	//该值表示,是否需要周期间隔的调整。全速设备不需要,因为它固定
    	param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
    	//全速设备,间隔时间固定为1000us
    	if (subs->speed == USB_SPEED_FULL)
    		/* full speed devices have fixed data packet interval */
    		ptmin = 1000;
    	if (ptmin == 1000)
    		/* if period time doesn't go below 1 ms, no rules needed */
    		param_period_time_if_needed = -1;
    
    	//设置,周期间隔的最小值,和最大值
    	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
    				     ptmin, UINT_MAX);
    
    	//下面一些列都是在添加规则,当修改对应的参数时,对应的回调函数将会被触发
    	if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
    				       hw_rule_rate, subs,
    				       SNDRV_PCM_HW_PARAM_FORMAT,
    				       SNDRV_PCM_HW_PARAM_CHANNELS,
    				       param_period_time_if_needed,
    				       -1)) < 0)
    		goto rep_err;
    	if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
    				       hw_rule_channels, subs,
    				       SNDRV_PCM_HW_PARAM_FORMAT,
    				       SNDRV_PCM_HW_PARAM_RATE,
    				       param_period_time_if_needed,
    				       -1)) < 0)
    		goto rep_err;
    	if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
    				       hw_rule_format, subs,
    				       SNDRV_PCM_HW_PARAM_RATE,
    				       SNDRV_PCM_HW_PARAM_CHANNELS,
    				       param_period_time_if_needed,
    				       -1)) < 0)
    		goto rep_err;
    	if (param_period_time_if_needed >= 0) {
    		err = snd_pcm_hw_rule_add(runtime, 0,
    					  SNDRV_PCM_HW_PARAM_PERIOD_TIME,
    					  hw_rule_period_time, subs,
    					  SNDRV_PCM_HW_PARAM_FORMAT,
    					  SNDRV_PCM_HW_PARAM_CHANNELS,
    					  SNDRV_PCM_HW_PARAM_RATE,
    					  -1);
    		if (err < 0)
    			goto rep_err;
    	}
    	//判断是否都是一些常规的采样率。见《usb声卡驱动(四)》
    	if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
    		goto rep_err;
    	return 0;
    
    rep_err:
    	//电源管理相关,进入suspend状态
    	snd_usb_autosuspend(subs->stream->chip);
    	return err;
    }
    

    依然是对hw里面的字段就行赋值。没有什么可记录的,一些关键位置见上面的注释

    上面是playback的open,接下来看看capture的open,如下:

    static int snd_usb_capture_open(struct snd_pcm_substream *substream)
    {
    	return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
    }
    

    他们调用到了同一个snd_usb_pcm_open函数中,也是对hw的各种初始化。

    虽然上面的函数没有什么可记录,但需要注意一下几点:

    1. 周期间隔的计算,即在《usb声卡驱动(三)》中谈到的“2的(bInterval-1)次方乘以125us”
    2. 根据不同的条件,hw里面的值可能会不同,此时使用了《usb声卡驱动(四)》的限制规则。举例如下:
    if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
    				       hw_rule_rate, subs,
    				       SNDRV_PCM_HW_PARAM_FORMAT,
    				       SNDRV_PCM_HW_PARAM_CHANNELS,
    				       param_period_time_if_needed,
    				       -1)) < 0)
    

    如果应用修改格式,通道,还有周期时间,那么hw_rule_rate函数就会被触发,
    它会根据各种要求,进行必要的设置。内部又是对hw字段的各种赋值,也没啥好记录的。

    总结就是:open里面是对runtime的hw的正确赋值。

    pcm的关闭

    有了前面的打开逻辑,现在直接进入substream的close回调中。如下:

    static int snd_usb_playback_close(struct snd_pcm_substream *substream)
    {
    	return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
    }
    
    static int snd_usb_capture_close(struct snd_pcm_substream *substream)
    {
    	return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
    }
    
    static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
    {
    	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
    	struct snd_usb_substream *subs = &as->substream[direction];
    
    	//停止usb端点。分别停止同步端点和数据端点
    	//至于usb端点如何停止,详见后面关于端点操作的详细介绍
    	stop_endpoints(subs, true);
    
    	if (!as->chip->shutdown && subs->interface >= 0) {
    		//切换接口的设置为0,因为设置0,表示了0带宽。用于释放usb资源
    		usb_set_interface(subs->dev, subs->interface, 0);
    		subs->interface = -1;
    	}
    
    	subs->pcm_substream = NULL;
    	//当pcm关闭时,电源状态进入一种挂起的状态,暂且不表
    	snd_usb_autosuspend(subs->stream->chip);
    
    	return 0;
    }
    

    上面的函数,会去调用stop_endpoint函数,如下:

    static void stop_endpoints(struct snd_usb_substream *subs, bool wait)
    {
    	//snd_usb_endpoint_stop停止给定的端点,主要的操作就是将端点的使用计数
    	//减一,如果使用计数变成0,则unlink所有激活的urb
    	if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags))
    		snd_usb_endpoint_stop(subs->sync_endpoint);
    
    	if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags))
    		snd_usb_endpoint_stop(subs->data_endpoint);
    
    	if (wait) {
    		//表示等待对应的端点中所有已经提交的队列被处理完成。
    		snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
    		snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
    	}
    }
    

    这个函数,根据需要,分别停止,同步端点和数据端点,并等到真正的端点关闭。关于同步端点和数据端点,可见《usb声卡驱动(二)》

    各个端点的操作函数的语义,见上面的注释

    hw参数设置

    在open了一个pcm,并正确的返回了一个流之后。常常通过IOCTL,获取这个pcm相关的硬件信息,然后应用选择不同的配置并设置硬件。

    在设置里面,分成了两种:hw,和sw。前者表示硬件参数,后者表示软件参数。

    先来看看hw的数据结构用下面表示

    struct snd_pcm_hw_params {
    	unsigned int flags;
    	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
    			       SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
    	struct snd_mask mres[5];	/* reserved masks */
    	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
    				        SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
    	struct snd_interval ires[9];	/* reserved intervals */
    	unsigned int rmask;		/* W: requested masks */
    	unsigned int cmask;		/* R: changed masks */
    	unsigned int info;		/* R: Info flags for returned setup */
    	unsigned int msbits;		/* R: used most significant bits */
    	unsigned int rate_num;		/* R: rate numerator */
    	unsigned int rate_den;		/* R: rate denominator */
    	snd_pcm_uframes_t fifo_size;	/* R: chip FIFO size in frames */
    	unsigned char reserved[64];	/* reserved for future */
    };
    
    1. flags:目前不知为何用,从源码上面看,跟限制规则有关
    2. masks:用于描述access、format、subformat这几个参数
    3. intervals:用于描述内核定义的所有interval参数.
    4. rmask:用户空间想要修改的参数bit集合。
    5. cmask:用户空间成功修改的参数bit集合。
    6. info: 表示硬件的一些参数,跟runtime的info一致,形如:SNDRV_PCM_INFO_XXX
    7. msbits: 有效位
    8. rate_num:采样率的分子
    9. rate_den:采样率的分母
    10. fifo_size:某些硬件的fifo大小

    当应用通过ioctl,传递SNDRV_PCM_IOCTL_HW_PARAMS命令时,驱动根据snd_pcm_hw_params和限制规则(open的时候添加的规则)来决定硬件的一些特性。

    当设置硬件参数时,pcm的hw_params回调会被触发.根据《usb声卡驱动(四)》可以知道应该在这个回调中,做一些硬件设置,包括buffer的分配。

    接下来看看usb声卡驱动的这个回调,如下:

    static int snd_usb_hw_params(struct snd_pcm_substream *substream,
    			     struct snd_pcm_hw_params *hw_params)
    {
    	struct snd_usb_substream *subs = substream->runtime->private_data;
    	struct audioformat *fmt;
    	int ret;
    
    	//调动alsa提供的buffer分配函数
    	//注意不要自己分配函数,因为该回调可能会被调用多次,如果自己修改需要注意内存的泄漏
    	//同时,分配的内存需要在hw_free回调中进行释放
    	ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
    					       params_buffer_bytes(hw_params));
    	if (ret < 0)
    		return ret;
    
    	//设置各种硬件参数
    	subs->pcm_format = params_format(hw_params);
    	subs->period_bytes = params_period_bytes(hw_params);
    	subs->period_frames = params_period_size(hw_params);
    	subs->buffer_periods = params_periods(hw_params);
    	subs->channels = params_channels(hw_params);
    	subs->cur_rate = params_rate(hw_params);
    
    	fmt = find_format(subs);
    	if (!fmt) {
    		dev_dbg(&subs->dev->dev,
    			"cannot set format: format = %#x, rate = %d, channels = %d\n",
    			   subs->pcm_format, subs->cur_rate, subs->channels);
    		return -EINVAL;
    	}
    
    	down_read(&subs->stream->chip->shutdown_rwsem);
    	//如果正处于shutdown状态则返回,否则继续设置参数
    	if (subs->stream->chip->shutdown)
    		ret = -ENODEV;
    	else
    		ret = set_format(subs, fmt);
    	up_read(&subs->stream->chip->shutdown_rwsem);
    	if (ret < 0)
    		return ret;
    
    	//need_setup_ep表示要配置usb使用的端点
    	//每一个端点在使用之前,都需要先设置参数,而每一次的参数修改,都需要重新配置usb端点
    	subs->interface = fmt->iface;
    	subs->altset_idx = fmt->altset_idx;
    	subs->need_setup_ep = true;
    
    	return 0;
    }
    

    上面的函数,都是对subs的赋值。其中需要注意的是snd_pcm_lib_alloc_vmalloc_buffer函数。
    它分配这个substream的buffer。它的内容如下:

    #define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \
    	_snd_pcm_lib_alloc_vmalloc_buffer \
    			(subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO)
    
    int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
    				      size_t size, gfp_t gfp_flags)
    {
    	struct snd_pcm_runtime *runtime;
    
    	if (PCM_RUNTIME_CHECK(substream))
    		return -EINVAL;
    	runtime = substream->runtime;
    	//重复调用的情况下,释放上一次分配的内存
    	if (runtime->dma_area) {
    		if (runtime->dma_bytes >= size)
    			return 0; /* already large enough */
    		vfree(runtime->dma_area);
    	}
    	//将分配的内存起始地址保存在dma_area,后面有用处
    	runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
    	if (!runtime->dma_area)
    		return -ENOMEM;
    	//分配的内存的大小
    	runtime->dma_bytes = size;
    	return 1;
    }
    

    这个函数调用__vmalloc函数,在常规内存,或者高端内存中分配buffer,注意,这里面没有DMA区域。
    分配完成之后,将地址,赋值给runtime的dma_area.

    虽然,这里的名字叫dma_area,但它并没有用到dma内存。

    总结:hw_params回调,进行进一步的初始化,并分配buffer

    sw参数设置

    设置完了硬件参数以后,接下来可以设置软件参数了。来看看软件参数的数据结构

    struct snd_pcm_sw_params {
    	int tstamp_mode;			/* timestamp mode */
    	unsigned int period_step;
    	unsigned int sleep_min;			/* min ticks to sleep */
    	snd_pcm_uframes_t avail_min;		/* min avail frames for wakeup */
    	snd_pcm_uframes_t xfer_align;		/* obsolete: xfer size need to be a multiple */
    	snd_pcm_uframes_t start_threshold;	/* min hw_avail frames for automatic start */
    	snd_pcm_uframes_t stop_threshold;	/* min avail frames for automatic stop */
    	snd_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
    	snd_pcm_uframes_t silence_size;		/* silence block size */
    	snd_pcm_uframes_t boundary;		/* pointers wrap point */
    	unsigned int proto;			/* protocol version */
    	unsigned int tstamp_type;		/* timestamp type (req. proto >= 2.0.12) */
    	unsigned char reserved[56];		/* reserved for future */
    };
    
    1. tstamp_mode:值为下面
    enum {
    	SNDRV_PCM_TSTAMP_NONE = 0,
    	SNDRV_PCM_TSTAMP_ENABLE,
    	SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE,
    };
    

    表示是否启用时间戳
    2. period_step:未见其用处,不知道有何用,查看源码也没弄明白,暂时先放放
    3. sleep_min:未见其用处
    4. avail_min:最小可用帧。到达这个之后,唤醒等待中的线程
    5. xfer_align:已过时,也未见其用处
    6. start_threshold:开始运行的阈值。
    7. stop_threshold:开始停止的阈值
    8. silence_threshold:xrun状态下,使用静默数据填充的阈值
    9. silence_size:silence数据块大小
    10. boundary:buffer的边界
    11. proto:protocol 版本
    12. tstamp_type:时间戳类型,值为

    enum {
    	SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,	/* gettimeofday equivalent */
    	SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,	/* posix_clock_monotonic equivalent */
    	SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW,    /* monotonic_raw (no NTP) */
    	SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW,
    };
    

    表示,runtime里面时间戳的模式。各个模式的定义,见上面的注释

    应用程序使用ioctl,传递SNDRV_PCM_IOCTL_SW_PARAMS命令,将用户空间的参数,设置进驱动。驱动将这些值,设置到对应的substream的runtime里面。

    这个设置并没有对应的回调会被触发。

    参数相关的释放

    在上面的参数设置中。可以看到有两个主要方向:

    1. 修改runtime中的各种各样的值
    2. 分配buffer

    runtime中的值随,runtime的释放而释放。runtime的产生在open时刻,因此,runtime的释放,应该在release时刻,注意并不是close时刻。runtime是由alsa分配的,相应的释放也由alsa管理,我们不讨论其细节。

    相应的buffer分配在hw_params时刻;那么buffer的释放就应该在hw_free时刻。这个buffer由usb声卡驱动分配,现在看一下它的释放细节,如下:

    static int snd_usb_hw_free(struct snd_pcm_substream *substream)
    {
    	struct snd_usb_substream *subs = substream->runtime->private_data;
    
    	subs->cur_audiofmt = NULL;
    	subs->cur_rate = 0;
    	subs->period_bytes = 0;
    	down_read(&subs->stream->chip->shutdown_rwsem);
    	if (!subs->stream->chip->shutdown) {
    		//端点的引用计数减一。为0时,unlink所有的urb
    		stop_endpoints(subs, true);
    		snd_usb_endpoint_deactivate(subs->sync_endpoint);
    		snd_usb_endpoint_deactivate(subs->data_endpoint);
    	}
    	up_read(&subs->stream->chip->shutdown_rwsem);
    	//释放hw_params中分配的内存
    	return snd_pcm_lib_free_vmalloc_buffer(substream);
    }
    

    主要的资源释放在snd_pcm_lib_free_vmalloc_buffer,即释放由snd_pcm_lib_alloc_vmalloc_buffer分配的buffer

    至此,已经翻阅完了,pcm设备的参数设置和释放

    接下来,应该进入一个关键的部分。以playback为例,先查看prepare。然后再查看开始,暂停,停止的操作。同时查看,端点的操作,以及数据传输情况。

    下篇见

    展开全文
  • US22为一款蓝牙+USB声卡二合一的音频转换器。可将USB音频流或蓝牙音频流转换成AES/EBU+平衡模拟立体声输出。前面板:USB接口:标准B型母口,可以当电源接口用,为设备供电。也可以当音频线用,此时设备为从机,需要...

    9278b420fb21bf0a73b3695f911c22e9.png

    c45d002ed1f754f726cd0e6808d54b5b.png

    US22为一款蓝牙+USB声卡二合一的音频转换器。可将USB音频流或蓝牙音频流转换成AES/EBU+平衡模拟立体声输出。

    前面板:

    USB接口:标准B型母口,可以当电源接口用,为设备供电。也可以当音频线用,此时设备为从机,需要主机送出音频流,比如当成电脑USB声卡。

    DC5V:外置DC5V电源接口,接口类型5.5*2.5

    后面板:

    AES:输出AES/EBU数字音频,采样率48KHz。

    L/R:平衡模拟左右声道输出

    注意事项:

    1、   蓝牙音频会优先USB音频解码送出到输出端口,所以如果要是用USB接口送入音频流,需要断开设备的蓝牙连接。

    2、   蓝牙支持以下格式解码:sbc、aac、aptx、aptx-HD,蓝牙版本5.1

    3、   当做电脑USB声卡使用时,即插即用,无需驱动,也无需外置电源。

    4、   蓝牙配对显示名称为:QCC3031-I2S

    展开全文
  • 客所思usb声卡通用驱动是一款声卡驱动类软件,是一个通用型的声卡驱动,软件功能十分强大,能够帮助用户解决客所思声卡不能发声或无法识别的问题。欢迎有需要的朋友下载体验!官方介绍客所思声卡是目前电脑市场上最...
  • 设置默认USB声卡.zip

    2021-04-01 00:42:27
    一个能指定USB声卡为默认的软件
  • 2019年3月,iCON官方发布了一款全球首创——全新一代“ProDrive III”USB声卡驱动,iCON所有系列USB声卡(包括带声卡的MIDI键盘)已全面启用ProDrive III !iCON ProDrive III由iCON的国际工程师团队微调的高品质模拟...

    2019年3月,iCON官方发布了一款全球首创——全新一代“ProDrive III”USB声卡驱动,iCON所有系列USB声卡(包括带声卡的MIDI键盘)已全面启用ProDrive III !

    76fac0c7ac717fb604a0f25fbfccc70e.png

    iCON ProDrive III由iCON的国际工程师团队微调的高品质模拟元件和电路,可同时支持标准模式和高性能模式,将卓越的音质、超低延迟和超快速处理结合起来。第三代是一个功能强大且灵活的音频控制面板,使您比以往更容易输入完美的声音。

    be8574d637cf5aeca5eb266f50c957db.png

    标准模式:更加优化,ASIO性能占用更低,应用于多任务处理时,更加稳定;

    高性能模式:达到超低延时,灵数据丢失。在录音场合能使录音更加完美。同时还加入了自动适应系统性能功能,匹配不同的电脑,用不同的延时数据,达到理想的录音效果。

    c9cd3d9751af4e19e9dd26e885276f39.png

    iCON ProDrive III的功能:

    24 bit, 96到192 khz 录制

    优质的AKM D/A转换器提供最高级的动态范围和信噪比,以获得清晰、干净的声音

    无间断地监测记录仪会零延迟反馈到监测混音器上

    为高级用户提供优化延迟模式的高级设置

    在最高配置和最低配置的电脑里,可切换USB传输模式释放处理资源

    68068533ea1b6b991f99d5ca3bf98481.png

    所有的iCON声卡都能在ProDrive III音频控制中心里使用。无论有没有数字音频工作站,都可以在现场或工作室,PD3允许您以任何方式使用电脑的音频应用程序。使用PD3 Plugin Host,可以连接你最喜欢的插件;将你最喜欢的插件链线后,保存为预设,能现场在舞台上直播调用它们。

    c6172df82f20c20968a3ae07c2c0fa27.png

    声卡是发挥你美妙音色的重要设备,无论你是在拍摄一部大电影,还是编辑网络视频;无论你是在广播或博客,在演播室表演,在线表演,还是在舞台上表演,iCON ProDrive III都能成就你想要的音色!

    d0826f5c3d97773e93c899c7daabc465.png
    展开全文
  • usb声卡asio驱动

    2014-09-07 13:18:43
    usb声卡asio驱动
  • 摘 要:本文介绍了基于S3C2410处理器平台,利用I2S总线的USB声卡系统设计。详细阐述了USB声卡通讯的实现,并且根据I2S总线DMA传输的特点实现了环形缓冲区,以提高系统性能,满足音频实时性的要求。关键词: USB声卡...
  • mos 设置教程 usb声卡

    2017-09-14 09:15:52
    外置 usb声卡 播放dsd音乐,foobar2000 播放器比方。下载驱动和播放器就能播放了。按照教程设置之后,一步一步就可以播放dsd音乐。
  • 软件介绍: Behringer百灵达bca2000驱动,一款全能的USB外置声卡音频工作站,专业级USB声卡是听歌唱歌的最佳工具,这个是它的驱动程序,使用前,需要在电脑上安装此驱动。
  • 摘 要:本文介绍了基于S3C2410处理器平台,利用I2S总线的USB声卡系统设计。详细阐述了USB声卡通讯的实现,并且根据I2S总线DMA传输的特点实现了环形缓冲区,以提高系统性能,满足音频实时性的要求。关键词: USB声卡...
  • Linux - UAC USB声卡

    2021-03-22 20:00:33
    Linux - UAC USB声卡UAC定义 最近项目里需要做一个linux平台的USB声卡,及通过USB插入Android设备,可识别成为一个USB声卡设备,并通过UAC采集录音 也可通过UAC播放音频的功能; UAC定义 任何USB设备在连接到USB...

    最近项目里需要做一个linux平台的USB声卡,及通过USB插入Android设备,可识别成为一个USB声卡设备,并通过UAC采集录音 也可通过UAC播放音频的功能;

    USB-HID定义

    USB HID类是USB设备的一个标准设备类,包括的设备非常多。HID类设备定义它属于人机交互操作的设备,用于控制计算机操作的一些方面,如USB鼠标、USB键盘、USB游戏操纵杆等。但HID设备类不一定要有人机接口,只要符合HID类别规范的设备都是HID设备。

    USB HID设备的一个好处就是操作系统自带了HID类的驱动程序,而用户无需去开发驱动程序,只要使用API系统调用即可完成通信。

    UAC定义

    任何USB设备在连接到USB接口后,主机检测到有新设备接入,会利用不同的请求命令(Request)查询该设备的属性,设备通过不同的描述符向主机报告自己的情况。包括设备的种类,设备的功能,设备具有的端点数量以及其他工作属性等等。在了解这些信息之后,主机就可以根据需要分配USB工作带宽。
    在USB中USB HOST 是通过各种描述符来识别设备的,有 设备描述符,接口描述符,端点描述符,字符描述符,报告描述符等
    USB HID 设备 (人机交互操作的设备) 是通过报告来传送数据的,报告有:输入报告 和 输出报告
    USB Audio Class,USB音频类,一个像USB这样的通用数据接口,可以有很多种实现数字音频数据传输的方式。不同的开发者可以根据自己的喜好和需求,定义任意的控制方式,传输模式,音频格式等等参数。

    本文档提供Rockchip平台基于Linux4.4内核的USB Gadget UAC (USB Audio Class)驱动的使用方法。Rockchip平台可以支持UAC1 (兼容USB Audio Class specification 1.0)和UAC2 (兼容USB Audio Class specification2.0)驱动,并且,这两个驱动都可以支持基础的录音和放音功能。此外, Rockchip平台还提供了UAC1 Legacy(需要实际的声卡支持,只支持放音功能)和Audio Source (只支持录音功能,但可以支持多达15种不同的采样率)。开发人员可以根据产品的实际需求来选择合适的UAC驱动。如果要支持音量调节/静音功能,需要添加HID的控制,目前发布的SDK还没有支持。开发人员可以参考如下的文档进行HID功能的开发。

    Kernel/Documentation/usb/gadget-testing.txt (参考 6. HID function)
    Kernel/Documentation/ABI/testing/configfs-usb-gadget-hid
    Universal Serial Bus Audio Device Class Specification for Basic Audio Devices (参考 8 HID Support in Basic
    Audio Devices)

    UAC设置

    Note:USB Audio 1.0 Specification在USB 2.0 core Specification之前完成,因此USB Audio 1.0 Specification没有高速模式(High Speed)这一概念。可以通过一些经验规则使得Audio 1.0兼容设备在特定的操作系统上实现高速模式。比如修改isochronous endpoint descriptor的blnterval4,目前尚没有详尽的经验规则保证在所有的操作系统上都能正常工作在高速模式下。
    Rockchip平台UAC1驱动支持USB Audio Class specification 1.0,支持录音和放音,并且不需要实际的声卡。UAC1驱动设置bInterval=4.
    默认支持:
    速率: High Speed
    采样率: playback和capture都为48 KHz,可以通过内核提供的接口配置为其他采样率
    声道数: playback和capture都为2 Channels,最多支持双声道,可以通过内核提供的接口配置为单声道
    位深度: playback和capture都为16 bits
    UAC1使用方法如下
    添加CONFIG-USB-CONFIGFSFUAC1-y到内核的defconfig
    以3308 EVB为例配置UAC1的脚本参考如下:

    mount -t configfs none /sys/kernel/config
    mkdir /sys/kernel/config/usb_gadget/rockchip -m 0770
    echo 0x2207 > /sys/kernel/config/usb_gadget/rockchip/idVendor
    echo 0x0019 > /sys/kernel/config/usb_gadget/rockchip/idProduct
    echo 0x0100 > /sys/kernel/config/usb_gadget/rockchip/bcdDevice
    mkdir /sys/kernel/config/usb_gadget/rockchip/strings/0x409 -m 0770
    echo "0123456789ABCDEF" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/serialnumber
    echo "rockchip" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/manufacturer
    echo "USB Audio Device" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/product
    mkdir /sys/kernel/config/usb_gadget/rockchip/configs/b.1 -m 0770
    mkdir /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409 -m 0770
    echo 500 > /sys/kernel/config/usb_gadget/rockchip/configs/b.1/MaxPower
    echo "uac1" >
    /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409/configuration
    mkdir /sys/kernel/config/usb_gadget/rockchip/functions/uac1.gs0
    ln -s /sys/kernel/config/usb_gadget/rockchip/functions/uac1.gs0
    /sys/kernel/config/usb_gadget/rockchip/configs/b.1/uac1.gs0
    echo ff400000.usb > /sys/kernel/config/usb_gadget/rockchip/UDC
    

    假如3308开机后,默认运行了ADB配置脚本,会导致上述的配置方法出错,在调试阶段,可以手动执行如下命令来配置UAC1功能。最终产品的USB配置脚本,需要根据实际的需求来整合ADB和UAC1的配置脚本。

    rm -rf /sys/kernel/config/usb_gadget/rockchip/configs/b.1/ffs.adb
    mkdir /sys/kernel/config/usb_gadget/rockchip/functions/uac1.gs0
    echo 0x0019 > /sys/kernel/config/usb_gadget/rockchip/idProduct
    echo 0x0100 > /sys/kernel/config/usb_gadget/rockchip/bcdDevice
    echo "USB Audio Device" > /sys/kernel/config/usb_gadget/rockchip/strings/0x409/product
    echo "uac1" >
    /sys/kernel/config/usb_gadget/rockchip/configs/b.1/strings/0x409/configuration
    cd /sys/kernel/config/usb_gadget/rockchip/configs/b.1
    ln -s ../../functions/uac1.gs0
    echo ff400000.usb > ../../UDC
    

    Note:"dProduct"可以根据产品自行定义,但不能与产品的其他USB Function idProduct冲突
    "UDC"为USB控制器名称,对应/sys/class/udc/控制器名称Windows会对设备驱动记忆,更改配置后最好卸载驱动,让Windows重新识别设备
    配置脚本执行成功后,连接USB到PC, PC端可以识别到USB Audio设备,如下图2-1 Windows-USB-Audio-Class1 ,图2-2 Ubuntu-USB-Audio-Class 1-Output和图2-3 Ubuntu-USB-Audio-Class1-input

    在Windows下识别出UAC
    在这里插入图片描述

    在ubuntu中识别出UAC在这里插入图片描述

    UAC 测试

    这里不详细阐述;
    提供个思路:
    1)将UAC插入到Windows中;确定正确枚举到设备
    2)测试UAC录音:UAC通过串口使用tinyplay播放一段格式正确的pcm音频,Windows端使用录音机录制,UAC播放完毕后,通过Windows的录音软件去判断录制到的音频文件是否是UAC播放的,对则合适;
    3)测试UAC放音:UAC通过串口使用tinycap录制一段格式正确的pcm音频,Windows端使用播放软件播放一点pcm,Windows播放完毕后,通过串口查看的录音去判断录制到的音频文件是否是Windows播放的,对则合适;

    展开全文
  • Emu 0204 USB声卡驱动.rar

    2019-08-30 21:12:19
    软件介绍: Emu 0204 USB声卡声卡驱动程序,支持32以及64位WINDOWS系统,官网上都找不到这个驱动,在网上辛苦收集来的,有用得着的朋友可以下载。
  • usb声卡驱动(一) 前面看了内核的启动,接下来就是驱动的学习。 正好手边有一个USB声卡,就准备以此为基础,进行usb声卡驱动的学习。 因此,在学些usb声卡之前,先看看usb驱动。然后再是alsa驱动,然后再是两者的...
  • 大约一个月前看到有人自制USB声卡,一直觉得电脑的集成声卡声音太垃圾,所以决定也效仿一个。  构思了一个晚上,第二天开始准备材料。什么贴片电阻贴片电容啊什么的好多东西啊,眼睛啊花了……  最重要的当然...
  • esi声卡驱动是一款的声卡驱动软件。此驱动程序能够解决用户在使用声卡设备过程中遇到的系统声音无法播放...MAYA22USB声卡介绍MAYA22USB声卡支持两路模拟输入和两路模拟输出,其中镀金RCA的输入接口、COMBO,欢迎下载体验
  • 基于PCM2912的USB声卡自制。
  • RS61/RS21USB声卡驱动是一类声卡驱动,专为语音聊天而生的usb声卡驱动,解决众多声音不兼容问题,在语音处理器方面拥有先进的专业技术,在你的电脑声音有点不正常时,不妨来试试重新安装驱动,欢迎下载使用!...
  • PCM2912_mini声卡,USB声卡包含原理图和PCB,喜欢的朋友可以捣腾下。
  • 为了获取USB声卡数据,在网上进行了大量的文章搜索,发现USB的库都是使用C语言写的,使用比较多的应属libusb了。 参考https://github.com/shenki/usbaudio-android-demo.git 1、libusb简介 libusb是一种高级别的...
  • RS61外置USB声卡驱动

    2011-11-27 01:32:03
    RS61外置USB声卡驱动,RS61外置USB声卡驱动,RS61外置USB声卡驱动。
  • 最近在鼓捣linux,打算用USB声卡录制监控声音,试过好几个都不是很理想 后来找了一个 linux专用usb声卡 ,外观比较常见,但是效果确实不错,接入系统后就识别了,顺便安利一下: 样子如下图: ...
  • USB声卡淘宝上随便能找得到,我就买了个最便宜的所谓的7.1声道的USB声卡,才8元。 但实际上也就2声道,而且音质不是很好,不过也能用了。 插上USB声卡,其实就可以使用了。因为树莓派上其实已经内置了当前流行的...
  • 基于STM32单片机设计的一款USB声卡设备,该设备插到电脑上,会将电脑的音频信号转化成数字信号。通过SPI发出到别的外设中。
  • 创新USB声卡驱动1.0

    2014-01-22 21:47:13
    这个是创新USB声卡V1.0版本驱动,支持WINDOWS XP系统。
  • 树莓派配置USB声卡

    千次阅读 2018-03-14 16:17:30
    树莓派配置USB声卡 $ cat /proc/asound/cards 0 [ALSA ]: bcm2835 - bcm2835 ALSA bcm2835 ALSA 1 [Device ]: USB-Audio - USB Audio Device C-Media Electro...
  • CM108 USB声卡IC

    2009-08-17 17:00:19
    CM108 USB声卡IC CM108 USB声卡IC
  • 电子-实验51USB声卡实验.rar,单片机/嵌入式STM32-F0/F1/F2

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,285
精华内容 514
关键字:

usb声卡