精华内容
下载资源
问答
  • Codec

    2020-04-01 16:14:13
    Redis data codec. Used during read and write Redis data. Several implementations are available: Codec class name Description org.redi...

    https://github.com/redisson/redisson/wiki/2.-Configuration#

    Redis data codec. Used during read and write Redis data. Several implementations are available:

    Codec class name Description
    org.redisson.codec.FstCodec FST up to 10x faster than JDK Serialization codec. Default codec
    org.redisson.codec.JsonJacksonCodec Jackson JSON codec
    org.redisson.codec.MarshallingCodec JBoss Marshalling binary codec
    org.redisson.codec.AvroJacksonCodec Avro binary json codec
    org.redisson.codec.SmileJacksonCodec Smile binary json codec
    org.redisson.codec.CborJacksonCodec CBOR binary json codec
    org.redisson.codec.MsgPackJacksonCodec MsgPack binary json codec
    org.redisson.codec.IonJacksonCodec Amazon Ion codec
    org.redisson.codec.KryoCodec Kryo binary codec
    org.redisson.codec.SerializationCodec JDK Serialization codec
    org.redisson.codec.LZ4Codec LZ4 compression codec
    org.redisson.codec.SnappyCodec Netty's implementation of Snappy compression codec
    org.redisson.codec.SnappyCodecV2 Snappy compression codec based on snappy-javaproject
    org.redisson.codec.TypedJsonJacksonCodec Jackson JSON codec which doesn't store type id (@class field) during encoding and doesn't require it for decoding
    org.redisson.client.codec.StringCodec String codec
    org.redisson.client.codec.LongCodec Long codec
    org.redisson.client.codec.ByteArrayCodec Byte array codec
    org.redisson.codec.CompositeCodec Used to mix different codecs as one

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • hello~大家新年好,已经好久没有更博了,刚刚在运行python文件的时候竟然报SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: tr这个错误,其实引起这个错误的原因就是转义...

        hello~大家新年好,已经好久没有更博了,刚刚在运行python文件的时候竟然报SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: tr这个错误,其实引起这个错误的原因就是转义的问题。

        举个例子,在文件中我传入的文件路径是这样的

    sys.path.append('c:\Users\mshacxiang\VScode_project\web_ddt')

        原因分析:在windows系统当中读取文件路径可以使用\,但是在python字符串中\有转义的含义,如\t可代表TAB,\n代表换行,所以我们需要采取一些方式使得\不被解读为转义字符。目前有3个解决方案

    1、在路径前面加r,即保持字符原始值的意思。

    sys.path.append(r'c:\Users\mshacxiang\VScode_project\web_ddt')

    2、替换为双反斜杠

    sys.path.append('c:\\Users\\mshacxiang\\VScode_project\\web_ddt')

    3、替换为正斜杠

    sys.path.append('c:/Users/mshacxiang/VScode_project/web_ddt')

     

    展开全文
  • 成功解决Python3版UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in 目录 解决问题 解决过程 解决方法 解决问题 UnicodeDecodeError: 'ascii' codec can't ...

    成功解决Python3版UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in

     

     

     

     

    目录

    解决问题

    解决过程

    解决方法


     

     

     

    解决问题

    UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)

     

     

     

    解决过程

    1、最近在做深度学习的项目,在调用GitHub上的文件时,想利用mnist_loader的数据集,没想到运行以后出现了错误UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)

     

    2、于是,笔者就各种百度啊,各种度,国内外的,但是答案差不多都有一种,就是添加以下代码

     

    3、可是,笔者在python中各种加入,各种尝试,还把utf8改为gbk试了好几次,又出现了这个错误,我去去去!

     

    4、笔者又不厌其烦的跑去百度,各种度,国内外的,最后发现了预料中的一件事,在Python 3.x中不好使了提示name reload’ is not defined,在3.x中已经被毙掉了被替换为

    import importlib
    importlib.reload(sys)

    并且,Python 3默认是utf8编码格式,我了各种去,心里一万只草泥马,同样是python,python2和python3咋就差别这么大呢!还要自行车?要啥自行车,啊啊啊!

     

     

    5、于是,笔者陷入了沉思,也就是睡着了,哈哈,开玩笑,继续谷歌、百度啦,直到发现了下边这句话,

     

    6、皇天不负有心人,哈哈,终于改对啦,谢谢小梦dream,感谢小梦这位仁兄

    将
    training_data, validation_data, test_data = cPickle.load(f)
    
    改为
    training_data, validation_data, test_data = cPickle.load(f,encoding='bytes')
    
    即可!

     

    7、哈哈,成功!搞定!努力总是又收获的,继续努力啦!

     

     

     

    解决方法

    training_data, validation_data, test_data = cPickle.load(f)

    改为

    training_data, validation_data, test_data = cPickle.load(f,encoding='bytes')


    哈哈,大功告成!

     

     

    展开全文
  • 平台 os版本 内核 MT6765 ..../kernel-4.9/sound/soc/mediatek/codec/mt6357/mtk-soc-codec-6357.c module_init(mtk_mt6357_codec_init); static int __init mtk_mt6357_codec_init(void) ...
    平台 os版本 内核
    MT6765 Android 9.0 kernel-4.9

    在嵌入式设备中,codec的作用可以简单的分为4种:

    1. PCM等信号进行D/A转换,把数字的隐僻信号转换为模拟信号。
    2. micLinein或者其他输入源的模拟信号进行A/D转换,把模拟的声音信号转变为cpu能够处理的数字信号。
    3. 对音频通路进行控制,比如播放音乐,收听调频收音机,或者接听电话的时候,在不同个场景中,音频信号在codec内的流通路线是不一样的
    4. 对音频信号做出相应的处理,例如音量的控制,功率的放大等等。
    audio驱动相关结构体 注释
    snd_soc_codec_driver 音频编解码芯片描述及操作函数,如控件/微件/音频路由的描述信息、时钟配置、IO 控制等
    snd_soc_dai_driver 这个结构体用来表示能够传输哪些格式的音频数据,并且提供了设置这些格式的函数

    ./kernel-4.9/sound/soc/mediatek/codec/mt6357/mtk-soc-codec-6357.c

    module_init(mtk_mt6357_codec_init);
    
    static int __init mtk_mt6357_codec_init(void)
    {
    	pr_debug("%s:\n", __func__);
    
        ... /* 省略部分非关键代码 */
        
    	InitGlobalVarDefault();
    	/* 注册codec的平台驱动 */
    	return platform_driver_register(&mtk_codec_6357_driver);
    }
    
    #ifdef CONFIG_OF
    static const struct of_device_id mt_soc_codec_63xx_of_ids[] = {
    	{.compatible = "mediatek,mt_soc_codec_63xx",},
    	{}
    };
    #endif
    
    static struct platform_driver mtk_codec_6357_driver = {
    	.driver = {
    		   .name = MT_SOC_CODEC_NAME,
    		   .owner = THIS_MODULE,
    #ifdef CONFIG_OF
    		   .of_match_table = mt_soc_codec_63xx_of_ids,
    #endif
    		   },
    	.probe = mtk_mt6357_codec_dev_probe,
    	.remove = mtk_mt6357_codec_dev_remove,
    }
    

    of_match_table./kernel-4.9/arch/arm/boot/dts/mt6765.dts文件中的

    mt_soc_codec_name {
             compatible = "mediatek,mt_soc_codec_63xx";
             use_hp_depop_flow = <0>; /* select 1: use, 0: not use */
             use_ul_260k = <0>; /* select 1: use, 0: not use */
    };
    

    compatible中的字符串匹配成功后,会调用到相应的probe函数。

    函数所在文件:
    ./kernel-4.9/sound/soc/mediatek/codec/mt6357/mtk-soc-codec-6357.c

    static int mtk_mt6357_codec_dev_probe(struct platform_device *pdev)
    {
    	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
    	if (pdev->dev.dma_mask == NULL)
    		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
    	if (pdev->dev.of_node) {
    		/* #define MT_SOC_CODEC_NAME "mt-soc-codec" */
    		/* 设置设备的名字 */
    		dev_set_name(&pdev->dev, "%s", MT_SOC_CODEC_NAME);
    		/* check if use hp depop flow */
    		of_property_read_u32(pdev->dev.of_node,
    				     "use_hp_depop_flow",
    				     &mUseHpDepopFlow);
    		pr_debug("%s(), use_hp_depop_flow = %d\n",
    			__func__, mUseHpDepopFlow);
    	} else {
    		pr_debug("%s(), pdev->dev.of_node = NULL!!!\n", __func__);
    	}
    	pr_debug("%s: dev name %s\n", __func__, dev_name(&pdev->dev));
    	/* 注册asoc框架中的codec驱动 */
    	return snd_soc_register_codec(&pdev->dev,
    				      &soc_mtk_codec, mtk_6357_dai_codecs,
    				      ARRAY_SIZE(mtk_6357_dai_codecs));
    }
    

    先分析注册的结构体soc_mtk_codec,再分析用来注册的函数snd_soc_register_codec

    结构体所在文件:
    ./kernel-4.9/sound/soc/mediatek/codec/mt6357/mtk-soc-codec-6357.c

    static struct snd_soc_codec_driver soc_mtk_codec = {
    	.probe = mt6357_codec_probe,
    	.remove = mt6357_codec_remove,
    	.read = mt6357_read,
    	.write = mt6357_write,
    };
    

    函数所在文件:
    ./kernel-4.9/sound/soc/mediatek/codec/mt6357/mtk-soc-codec-6357.c

    static int mt6357_codec_probe(struct snd_soc_codec *codec)
    {
    	int ret;
    
    	pr_debug("%s()\n", __func__);
    	if (mInitCodec == true)
    		return 0;
    	/* add codec controls */
    	snd_soc_add_codec_controls(codec, mt6357_snd_controls,
    				   ARRAY_SIZE(mt6357_snd_controls));
    	snd_soc_add_codec_controls(codec, mt6357_UL_Codec_controls,
    				   ARRAY_SIZE(mt6357_UL_Codec_controls));
    	snd_soc_add_codec_controls(codec, mt6357_pmic_Test_controls,
    				   ARRAY_SIZE(mt6357_pmic_Test_controls));
    	snd_soc_add_codec_controls(codec, Audio_snd_auxadc_controls,
    				   ARRAY_SIZE(Audio_snd_auxadc_controls));
    	/* here to set  private data */
    	mCodec_data = kzalloc(sizeof(struct mt6357_codec_priv), GFP_KERNEL);
    	if (!mCodec_data) {
    		/*pr_debug("Failed to allocate private data\n");*/
    		return -ENOMEM;
    	}
    	snd_soc_codec_set_drvdata(codec, mCodec_data);
    	memset((void *)mCodec_data, 0, sizeof(struct mt6357_codec_priv));
    	mt6357_codec_init_reg(codec);
    	InitCodecDefault();
    	efuse_current_calibrate =
    		read_efuse_hp_impedance_current_calibration();
    	mInitCodec = true;
    	/* 创建一个名为 "dc_trim_thread" 的内核线程 */
    	dc_trim_task = kthread_create(dc_trim_thread, NULL, "dc_trim_thread");
    	if (IS_ERR(dc_trim_task)) {
    		ret = PTR_ERR(dc_trim_task);
    		dc_trim_task = NULL;
    		pr_debug("%s(), create dc_trim_thread failed, ret %d\n",
    			 __func__, ret);
    	} else {
    		/* 唤醒执行前面创建的 "dc_trim_thread" 内核线程 */
    		wake_up_process(dc_trim_task);
    	}
    	return 0;
    }
    

    mt6357_codec_probe中对codec control设备进行了创建。Control接口主要让用户空间的应用程序(alsa-lib)可以访问和控制音频codec芯片中的多路开关,滑动控件等。对于Mixer(混音)来说,Control接口显得尤为重要,从ALSA 0.9.x版本开始的新版本中,所有的mixer工作都是通过control接口的API来实现的。使用snd_kcontrol_new结构来定义一个Control项,根据codec的芯片手册进行构造snd_kcontrol_new。配置codec的统一的接口就是snd_kcontrol,一个snd_kcontrol表示一个功能(可能是一个寄存器的某些位),每个snd kcontrol中有自己的读写函数。一个声卡有多个kcontrol,一个kcontrol对应着一个具体的控制功能,比如:音量,开关录音。kcontrol中有先关的函数来设置相应的功能。snd_kcontrol对应的是功能,其寄存器配置由codec驱动负责。

    代码所在文件:
    ./kernel-4.9/sound/soc/mediatek/codec/mt6357/mtk-soc-codec-6357.c

    static const struct snd_kcontrol_new mt6357_snd_controls[] = {
    	SOC_ENUM_EXT("Audio_Amp_R_Switch", Audio_DL_Enum[0], Audio_AmpR_Get,
    		     Audio_AmpR_Set),
    	SOC_ENUM_EXT("Audio_Amp_L_Switch", Audio_DL_Enum[1], Audio_AmpL_Get,
    		     Audio_AmpL_Set),
    	SOC_ENUM_EXT("Voice_Amp_Switch", Audio_DL_Enum[2], Voice_Amp_Get,
    		     Voice_Amp_Set),
    	SOC_ENUM_EXT("Speaker_Amp_Switch", Audio_DL_Enum[3],
    		     Speaker_Amp_Get, Speaker_Amp_Set),
    	SOC_ENUM_EXT("Headset_Speaker_Amp_Switch", Audio_DL_Enum[4],
    		     Headset_Speaker_Amp_Get,
    		     Headset_Speaker_Amp_Set),
    	SOC_ENUM_EXT("Headset_PGAL_GAIN", Audio_DL_Enum[5],
    		     Headset_PGAL_Get, Headset_PGAL_Set),
    	SOC_ENUM_EXT("Headset_PGAR_GAIN", Audio_DL_Enum[6],
    		     Headset_PGAR_Get, Headset_PGAR_Set),
    	SOC_ENUM_EXT("Handset_PGA_GAIN", Audio_DL_Enum[7], Handset_PGA_Get,
    		     Handset_PGA_Set),
    	SOC_ENUM_EXT("Lineout_PGAR_GAIN", Audio_DL_Enum[8],
    		     Lineout_PGAR_Get, Lineout_PGAR_Set),
    	SOC_ENUM_EXT("Lineout_PGAL_GAIN", Audio_DL_Enum[9],
    		     Lineout_PGAL_Get, Lineout_PGAL_Set),
    	SOC_ENUM_EXT("AUD_CLK_BUF_Switch", Audio_DL_Enum[10],
    		     Aud_Clk_Buf_Get, Aud_Clk_Buf_Set),
    	SOC_ENUM_EXT("Ext_Speaker_Amp_Switch", Audio_DL_Enum[11],
    		     Ext_Speaker_Amp_Get,
    		     Ext_Speaker_Amp_Set),
    	SOC_ENUM_EXT("Receiver_Speaker_Switch", Audio_DL_Enum[11],
    		     Receiver_Speaker_Switch_Get,
    		     Receiver_Speaker_Switch_Set),
    	SOC_ENUM_EXT("PMIC_REG_CLEAR", Audio_DL_Enum[12],
    		     PMIC_REG_CLEAR_Get, PMIC_REG_CLEAR_Set),
    	SOC_SINGLE_EXT("Codec_ADC_SampleRate", SND_SOC_NOPM,
    		       0, MAX_UL_SAMPLE_RATE, 0, codec_adc_sample_rate_get,
    			codec_adc_sample_rate_set),
    	SOC_SINGLE_EXT("Codec_DAC_SampleRate", SND_SOC_NOPM,
    		       0, MAX_DL_SAMPLE_RATE, 0, codec_dac_sample_rate_get,
    			codec_dac_sample_rate_set),
    	SOC_DOUBLE_EXT("DcTrim_DC_Offset", SND_SOC_NOPM, 0, 1, 0x20000, 0,
    		       pmic_dc_offset_get, pmic_dc_offset_set),
    	SOC_SINGLE_EXT("[HP+SPK] DcTrim_DC_Offset", SND_SOC_NOPM,
    		       0, 0x10000, 0, pmic_dc_offset_spk2hp_get,
    		       pmic_dc_offset_spk2hp_set),
    	SOC_ENUM_EXT("Dctrim_Control_Switch", Audio_DL_Enum[13],
    		     pmic_dctrim_control_get, pmic_dctrim_control_set),
    	SOC_SINGLE_EXT("Audio HP ImpeDance Setting",
    		       SND_SOC_NOPM, 0, 0x10000, 0,
    		       hp_impedance_get, hp_impedance_set),
    	SOC_ENUM_EXT("Headphone Plugged In", Audio_DL_Enum[0],
    		     hp_plugged_in_get, hp_plugged_in_set),
    	SOC_ENUM_EXT("Apply_N12DB_Gain", Audio_DL_Enum[14],
    		     apply_n12db_get, apply_n12db_set),
    }
    

    我们想要使用codec的相关功能,肯定就需要先将它注册到内核中,那么我们需要用什么函数把codec注册到内核中呢?
    答案是,用snd_soc_register_codec进行向内核完成对codec的注册。

    这里简单分析一下snd_soc_register_codec函数,它向ASoC core注册了一个codec
    函数所在文件:
    ./kernel-4.9/sound/soc/soc-core.c

    /**
     * snd_soc_register_codec - Register a codec with the ASoC core
     *
     * @dev: The parent device for this codec
     * @codec_drv: Codec driver
     * @dai_drv: The associated DAI driver
     * @num_dai: Number of DAIs
     */
    int snd_soc_register_codec(struct device *dev,
    			   const struct snd_soc_codec_driver *codec_drv,
    			   struct snd_soc_dai_driver *dai_drv,
    			   int num_dai)
    {
    	struct snd_soc_dapm_context *dapm;
    	struct snd_soc_codec *codec;
    	struct snd_soc_dai *dai;
    	int ret, i;
    
    	dev_dbg(dev, "codec register %s\n", dev_name(dev));
    
    	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
    	if (codec == NULL)
    		return -ENOMEM;
    
    	codec->component.codec = codec;
    
    	/* 控件的初始化,代码层面上来说就是初始化component */
    	ret = snd_soc_component_initialize(&codec->component,
    			&codec_drv->component_driver, dev);
    	if (ret)
    		goto err_free;
    
    	if (codec_drv->probe)
    		codec->component.probe = snd_soc_codec_drv_probe;
    	if (codec_drv->remove)
    		codec->component.remove = snd_soc_codec_drv_remove;
    	if (codec_drv->write)
    		codec->component.write = snd_soc_codec_drv_write;
    	if (codec_drv->read)
    		codec->component.read = snd_soc_codec_drv_read;
    	codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
    
    	dapm = snd_soc_codec_get_dapm(codec);
    	dapm->idle_bias_off = codec_drv->idle_bias_off;
    	dapm->suspend_bias_off = codec_drv->suspend_bias_off;
    	if (codec_drv->seq_notifier)
    		dapm->seq_notifier = codec_drv->seq_notifier;
    	if (codec_drv->set_bias_level)
    		dapm->set_bias_level = snd_soc_codec_set_bias_level;
    	codec->dev = dev;
    	codec->driver = codec_drv;
    	codec->component.val_bytes = codec_drv->reg_word_size;
    
    #ifdef CONFIG_DEBUG_FS
    	codec->component.init_debugfs = soc_init_codec_debugfs;
    	codec->component.debugfs_prefix = "codec";
    #endif
    
    	if (codec_drv->get_regmap)
    		codec->component.regmap = codec_drv->get_regmap(dev);
    
    	for (i = 0; i < num_dai; i++) {
    		fixup_codec_formats(&dai_drv[i].playback);
    		fixup_codec_formats(&dai_drv[i].capture);
    	}
    
    	/* 在这里注册codec_dai */
    	ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false);
    	if (ret < 0) {
    		dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret);
    		goto err_cleanup;
    	}
    
    	list_for_each_entry(dai, &codec->component.dai_list, list)
    		dai->codec = codec;
    
    	mutex_lock(&client_mutex);
    	snd_soc_component_add_unlocked(&codec->component);
    	list_add(&codec->list, &codec_list);
    	mutex_unlock(&client_mutex);
    
    	dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n",
    		codec->component.name);
    	return 0;
    
    err_cleanup:
    	snd_soc_component_cleanup(&codec->component);
    err_free:
    	kfree(codec);
    	return ret;
    }
    

    snd_soc_register_codec函数完成了对snd_soc_codec结构体的分配设置以及注册,它将snd_soc_codec_driver赋值给codec->driver,将snd_soc_dai_driver则注册到codec->component里,将创建的codec->component加到全局列表component_list中,将创建的codec加到全局列表codec_list中,方便后续注册machine driver时调用到。

    任何一个结构体想要注册进内核之前,都需要将其进行初始化,那么在将codec->component注册加入到全局列表component_list之前,由谁对codec->component进行初始化呢?
    我们在函数snd_soc_register_codec简单看一下代码执行流程,就可以发现,最有可能对codec->component进行初始化的函数是snd_soc_component_initialize。实际上,就是在snd_soc_component_initialize中实现对codec->component的初始化的。

    函数所在文件:
    ./kernel-4.9/sound/soc/soc-core.c

    static int snd_soc_component_initialize(struct snd_soc_component *component,
    	const struct snd_soc_component_driver *driver, struct device *dev)
    {
    	struct snd_soc_dapm_context *dapm;
    
    	component->name = fmt_single_name(dev, &component->id);
    	if (!component->name) {
    		dev_err(dev, "ASoC: Failed to allocate name\n");
    		return -ENOMEM;
    	}
    
    	component->dev = dev;
    	component->driver = driver;
    	component->probe = component->driver->probe;
    	component->remove = component->driver->remove;
    
    	dapm = &component->dapm;
    	dapm->dev = dev;
    	dapm->component = component;
    	dapm->bias_level = SND_SOC_BIAS_OFF;
    	dapm->idle_bias_off = true;
    	if (driver->seq_notifier)
    		dapm->seq_notifier = snd_soc_component_seq_notifier;
    	if (driver->stream_event)
    		dapm->stream_event = snd_soc_component_stream_event;
    
    	component->controls = driver->controls;
    	component->num_controls = driver->num_controls;
    	component->dapm_widgets = driver->dapm_widgets;
    	component->num_dapm_widgets = driver->num_dapm_widgets;
    	component->dapm_routes = driver->dapm_routes;
    	component->num_dapm_routes = driver->num_dapm_routes;
    
    	INIT_LIST_HEAD(&component->dai_list);
    	mutex_init(&component->io_mutex);
    
    	return 0;
    }
    

    我们注册了codec后,肯定需要和machine以及platform进行数据交互的,那么谁来帮忙对信息进行搬运呢?
    答案是codec_dai,即音频解码器的数字音频接口。同理,想要使用它,也需要分配设置注册一个codec_dai相应的结构体,才能真正的来使用它。

    函数所在文件:
    ./kernel-4.9/sound/soc/soc-core.c

    /**
     * snd_soc_register_dais - Register a DAI with the ASoC core
     *
     * @component: The component the DAIs are registered for
     * @dai_drv: DAI driver to use for the DAIs
     * @count: Number of DAIs
     * @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the
     *                     parent's name.
     */
    /*************************************************************************
     * 在snd_soc_register_dais函数内遍历snd_soc_dai_driver 列表,通过soc_add_dai
     * 将每个dai都添加到component的dai_list。 
     *************************************************************************/
    static int snd_soc_register_dais(struct snd_soc_component *component,
    	struct snd_soc_dai_driver *dai_drv, size_t count,
    	bool legacy_dai_naming)
    {
    	struct device *dev = component->dev;
    	struct snd_soc_dai *dai;
    	unsigned int i;
    	int ret;
    
    	dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);
    
    	component->dai_drv = dai_drv;
    
    	for (i = 0; i < count; i++) {
    
    		dai = soc_add_dai(component, dai_drv + i,
    				count == 1 && legacy_dai_naming);
    		if (dai == NULL) {
    			ret = -ENOMEM;
    			goto err;
    		}
    	}
    
    	return 0;
    
    err:
    	snd_soc_unregister_dais(component);
    
    	return ret;
    }
    

    不知道你们有没有留意到soc_add_dai这里函数,非常的明显,一看就知道是用来将codec_dai添加到对应的dai_list链表中 。

    在这里面,分配了一个snd_soc_dai结构体指针,并保存在指针变量dai中,然后进行了一系列的初始化(包括对daiidnamedevcomponentdriver等成员变量的设置)后,将它添加到了component->dai_list中。

    函数所在文件:
    ./kernel-4.9/sound/soc/soc-core.c

    /* Create a DAI and add it to the component's DAI list */
    static struct snd_soc_dai *soc_add_dai(struct snd_soc_component *component,
    	struct snd_soc_dai_driver *dai_drv,
    	bool legacy_dai_naming)
    {
    	struct device *dev = component->dev;
    	struct snd_soc_dai *dai;
    
    	dev_dbg(dev, "ASoC: dynamically register DAI %s\n", dev_name(dev));
    
    	dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
    	if (dai == NULL)
    		return NULL;
    
    	/*
    	 * Back in the old days when we still had component-less DAIs,
    	 * instead of having a static name, component-less DAIs would
    	 * inherit the name of the parent device so it is possible to
    	 * register multiple instances of the DAI. We still need to keep
    	 * the same naming style even though those DAIs are not
    	 * component-less anymore.
    	 */
    	if (legacy_dai_naming &&
    	   (dai_drv->id == 0 || dai_drv->name == NULL)) {
    		dai->name = fmt_single_name(dev, &dai->id);
    	} else {
    		dai->name = fmt_multiple_name(dev, dai_drv);
    		if (dai_drv->id)
    			dai->id = dai_drv->id;
    		else
    			dai->id = component->num_dai;
    	}
    	if (dai->name == NULL) {
    		kfree(dai);
    		return NULL;
    	}
    
    	dai->component = component;
    	dai->dev = dev;
    	dai->driver = dai_drv;
    	if (!dai->driver->ops)
    		dai->driver->ops = &null_dai_ops;
    
    	list_add(&dai->list, &component->dai_list);
    	component->num_dai++;
    
    	dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
    	return dai;
    }
    

    在这个函数里,有一个非常需要注意的一点就是,在这个函数中,会将dai_drvname 拷贝给dainame,为什么需要做这么一步呢?
    首先,我们都知道,codec dai实际上是一个通讯接口抽象出来的一个结构体,它仅仅是一个接口,需要被使用的,被使用的话,那么就应该要有使用的对象呀,这个对象有两个,一个是machine,一个是codec,因为codec dai本身就包含在codec里,所以不需要通过名字来找到codec dai,因此,很明显,它是方便machine找到对应的对应的codec dai的,也就是说,它会被用来让Machine driver通过这个name来找到codec dai的。

    我们将codec放进了codec_list链表,将codec_dai放进了dai_list链表中,并且都与component建立了联系,接下来,就需要将包含有codeccodec_daicomponent放入component_list链表中,那么应该通过那个函数放入呢?
    答案是snd_soc_component_add_unlocked,是不是很熟悉?因为在platform驱动中也用相同的函数将包含有paltformcpu_daicomponent添加到component_list链表中

    static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
    {
    	if (!component->write && !component->read) {
    		if (!component->regmap)
    			component->regmap = dev_get_regmap(component->dev, NULL);
    		if (component->regmap)
    			snd_soc_component_setup_regmap(component);
    	}
    
    	/* 将component_list添加进链表队列component->list */
    	list_add(&component->list, &component_list);
    	INIT_LIST_HEAD(&component->dobj_list);
    }
    

    到了这里,codeccodec_dai部分的驱动就注册完成了。

    展开全文
  • 0x00 问题引出: 最近在做一个买房自动化分析Python脚本,需要爬取网页。 在使用urllib获取reqest的response的时候,还要进行编码转换。...UnicodeDecodeError: 'utf-8' codec can't decode byte 0x
  • Audio Codec

    千次阅读 2018-08-30 16:57:40
    在移动设备中,Codec的作用可以归结为4种,分别是: 1.对PCM等信号进行D/A转换,把数字的音频信号转换为模拟信号 2.对Mic、Linein或者其他输入源的模拟信号进行A/D转换,把模拟的声音信号转变CPU能够处理的数字...
  • 最近写了一个Python小程序,用来统计...UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xa1 in position 0: invalid start byte 后来经过不断查找终于找到了解决办法。 由于我在程序中设定文件打开的...
  • Netty Codec框架

    千次阅读 2018-05-30 14:55:16
    什么是 Codec编写一个网络应用程序需要实现某种 codec (编解码器),codec的作用就是将原始字节数据与目标程序数据格式进行互转。网络中都是以字节码的数据形式来传输数据的,codec 由两部分组成:decoder(解码器)和...
  • ‘utf-8’ codec can’t decode byte 0xff in position 0: invalid start byte觉得有用的话,欢迎一起讨论相互学习~Follow Me今天使用语句image_raw_data_jpg = tf.gfile.FastGFile('../test_images/test_1.jpg', 'r'...
  • commons-codec-1.8官方JAR包程序文件

    万次下载 热门讨论 2013-05-10 10:34:30
    commons-codec-1.8官方JAR包,供亲们下载~~~
  • Codec2简介

    千次阅读 2020-04-16 13:10:29
    [注] 该文章简要介绍了Codec 2.0是什么,如有错误与遗漏之处,欢迎指出。 谷歌在2019年发布的Android Q上提供了一套新的MediaCodec实现框架--Codec 2.0,这一套新的框架是相对于旧的ACodec与OMX而言的。Codec 2.0的...
  • ASOC之Codec

    千次阅读 2018-10-27 09:50:02
    ASOC的出现是为了让Codec独立于CPU,减少和CPU之间的耦合,这样同一个Codec驱动无需修改就可以适用任何一款平台。还是以下图做参考例子: 在Machine中已经知道,snd_soc_dai_link结构就指明了该Machine所使用的...
  • Apache Commons Codec 1.10

    热门讨论 2015-08-12 14:57:28
    修改了包名后的Apache Commons Codec 1.10的jar包,为了满足Android端的加密需求,解决java.lang.NoSuchMethodError: org.apache.commons.codec.binary.Base64.encodeBase64String异常。
  • 今天,练习一个通过读取...在读取Walden.txt文本时,出现了“UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence”错误提示。 错误的意思是:Unicode的解码(Dec
  • logstash Codec

    千次阅读 2016-08-23 15:41:18
    Logstash 使用一个名叫FileWatch的Ruby Gem库来监听文件变化,这个库支持glob扩展文件路径, 而且会记录一个叫.sincedb的数据库文件来跟踪被监听日志文件的当前读取位置,所以,不要担心...Codec 来自Coder/decoder
  • 4.2.1 Codec基类

    千次阅读 2015-11-01 09:33:49
    在codecs模块里定义了与codec对象进行交互的接口,也可以使用它作为其它编解码的基类。 在Python里要求codec对象需要有四个接口:无状态的encoder,无状态的decoder,StreamReader和StreamWriter。而StreamReader和...
  • 虚拟Codec设计思路

    2020-06-15 17:38:39
    虚拟Codec设计思路就是只提供SoC到Codec端的PCM接口,Codec端的内部路由不做控制。统一化代码时需要将平台端与Codec端代码分析,设计思路如下所示: 虚拟Codec平台化
  • Codec简介 在移动设备中,Codec的作用可以归结为4种,分别是: 对PCM等信号进行D/A转换,把数字的音频信号转换为模拟信号 对Mic、Linein或者其他输入源的模拟信号进行A/D转换,把模拟的声音信号转变CPU能够...
  • slic codec

    千次阅读 2013-08-29 14:52:36
    今天突然对slic codec有了新的理解。。。 slic的作用一般是让交换机知道话机的摘挂机状态、和改变话机的状态,类似信令的作用。 codec就是模数转换、编码,类似处理媒体的作用。
  • alsa 添加codec

    千次阅读 2017-01-04 19:19:30
    嵌入式Linux alsa codec 驱动
  • 升级了Android studio 3.0+出现了:Error:Could not find commons-codec.jar (commons-codec:commons-codec:1.6).Searched in the following locations: file:/C:/Program Files/Android Studio/gradle/m2...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,577
精华内容 15,030
热门标签
关键字:

codec