MLT媒体程序框架03:滤镜——loudness
EBU R.128协议
引用链接
EBU
的全称为European Broadcasting Union ,既欧洲广播联盟,为欧洲与北非各广播业者(包含广播电台与电视台)的合作组织,成立于1950年2月12日,有五十多个正式加盟国,总部位于瑞士日内瓦,目前中国是EBU的准会员。
EBU R.128
实质上是欧洲广播联盟出的一个关于响度控制的建议书,该建议书在ITU-R BS.1770标准的(国际广播联盟规定的音频节目响度及真峰值的测量算法)基础之上,对响度的被测主体、积分窗长等细节作了更加明确的定义。
响度和动态范围的定义与相关的计量单位
-
响度(Loudness)
的定义: 在声学中,响度是人对声音压力的主观感受,也是听觉的一种属性,根据这种属性,可以对声音进行排序,如从安静排列到响亮,亦或者从响亮排列至安静。响度虽是声音的物理属性,但其却与听者的生理感受,心理感受息息相关,准确来说这属于心理物理学的范畴了。 -
音量单位dBFS与dB
: 首先dBFS与dB都是分贝的意思,而分贝一般指的就是音量大小。 dBFS全称decibels relative to full scale,什么叫full scale呢?既是满刻度,具体来讲是将0作为这种满刻度单位的最大值(也就是说此类值均为负数),凡是带FS后缀的计量单位都可这样理解(如LUFS或LKFS)。dB常用来形容一个音量到目标音量的“距离”,比如需要将一个信号从-4dBFS提升至-1dBFS,那么就需要对-4dBFS做3dB的提升操作。在业界,dBFS常被简称为dB,如-4dB等等。 -
动态范围
: 用通俗不严谨的话来说,动态范围指的是最大音量与最小音量之间的“距离”值,这个“距离”值就被称为动态范围,比如一段音频中的最大音量为-2dBFS,最小音量为-8dBFS,那么它的动态范围就是6dB。站在AD转换器的角度来说,动态范围指的是信号可以达到的最大不失真电平与本底噪声的差值。 -
EBU响度单位LUFS
: LUFS的全称为Loudness units relative to full scale,既相对完整刻度的响度单位。广电行业中,LUFS是有一个目标响度值的,那就是-23LUFS,该值是广播世界的终极响度参考值!LUFS的数值越大,其响度就越大。至于为什么是-23LUFS,笔者暂未做深入研究。另外,LKFS是国际广播联盟用的单位,与LUFS差不多。 -
EBU响度单位LU
: LU的全称为Loudness units,通常1LU“等同于”1dB(仅仅是理解层面上的“相等”),常用来形容两个LUFS之间的“距离”,如-25LUFS与-18LUFS间差了7LU。综上所述,dBFS与LUFS, dB与LU,虽测量算法不同,但其含义却是相似的。
响度示值,响度范围和真峰值的介绍
瞬时响度 Momentary Loudness
: 瞬时响度指的是400MS(毫秒)内的响度,并每过100ms进行一次更新,响应相当灵敏。短期响度 Short Term Loudness
: 短期响度是提取3秒以内的信号,表达的是3S内的平均响度。综合响度 Integrated Loudness
: 综合响度指的是整段音频的平均响度。响度范围 Loudness Range
: 响度范围,经常被简称为LRA,其代表的是两个LUFS之间的“距离”,如一段音频的最小响度为-25LUFS,最大响度为-18LUFS,其间差了7LU,既代表该音频的响度范围为7LU。响度范围与动态范围表达的是一个意思,只是测量方法不一样。真峰值 True Peak
: 在说真峰值之前,先用通俗的话来说说峰值是什么,峰值就是波形振幅的波峰值(波形有波谷和波峰之分),说白了就是波形瞬态的最大电平值。那为什么要在峰值之前加个“真”字呢?原因是这样的,以前有一种峰值测量方法,只有当峰值的持续时间超过一定的时间时(通常是几毫秒),才会计算出比较准确的峰值,这种测量算法被称为准峰值(QPPM)。而EBU给出了一种新的算法,无论它的持续时间有多短,都能正确的测量出其波形的真实峰值水平,故此,称其为真峰值。那么响度表中的真峰值指示条是用来干嘛的呢?它是用来检测信号有没有过载的,一旦信号过载就会被削波造成信号失真,正因如此,EBU给出建议为真峰值不要超过-1dBTP,目的就是防止信号产生过载削波,其单位为dBTP(dB True Peak真实峰值),对应的值是dBFS值。
双遍滤镜(loudness)
主要用于音频向度的精准标准化
,其核心作用是通过两次处理(Double Pass)分析音频特征并应用目标响度参数,确保输出音频符合行业标准(如EBU R128 或 ITU-R BS.1770),同时优化动态范围控制
使用方式
One Pass: 调用滤镜分析得到result
std::string AudioAnalyze::analyzeAudio(const std::string &path,int trimIn,int trimOut) {Producer producer(getGlobalProfile(), nullptr,path.c_str());if(producer.get_length() <= 1 || producer.get_int("audio_index") == -1){std::cout << "analyzeAudio no effect" << std::endl;return "";}if(trimOut > 0){producer.set_in_and_out(trimIn,trimOut);}Filter filter(getGlobalProfile(),"loudness");filter.set("program",-29);producer.attach(filter);Consumer consumer(getGlobalProfile(), "null");consumer.set("terminate_on_pause",0);consumer.connect(producer);consumer.start();while (!consumer.is_stopped()) {// ignoreif(filter.property_exists("results")){const char *results = filter.get("results");if(results != nullptr) {std::cout << "analyzeAudio results:" << results << std::endl;consumer.stop();return results;} else {std::cout << "analyzeAudio results:" << "error: key is null" << std::endl;return "";}}}return "";
}
Two Pass: 把result写入滤镜参数中,则会自动调整目标响度
std::shared_ptr<Filter> loudnessFilter{nullptr};
if (!results.empty()) {loudnessFilter = std::make_shared<Filter>(getGlobalProfile(), "loudness");loudnessFilter->set("program", configuration.aiDefaultLoudness);loudnessFilter->set("disable", 0);loudnessFilter->set("reload", 1);auto length = results.length() + 1;char *result = (char *) malloc(results.length() + 1);memcpy((void *) result, (const void *) results.c_str(), results.length());result[length - 1] = '\0';loudnessFilter->set("results", result);
}
loudnessFilter->set_in_and_out(trimIn, trimOut);
childClipInfo->producer->attach(*loudnessFilter);
关键源码分析
filter_get_audio
static int filter_get_audio(mlt_frame frame,void **buffer,mlt_audio_format *format,int *frequency,int *channels,int *samples)
{mlt_filter filter = mlt_frame_pop_audio(frame);mlt_properties properties = MLT_FILTER_PROPERTIES(filter);mlt_service_lock(MLT_FILTER_SERVICE(filter));// Get the producer's audio*format = mlt_audio_f32le;mlt_frame_get_audio(frame, buffer, format, frequency, channels, samples);char *results = mlt_properties_get(properties, "results");if (buffer && buffer[0] && results && strcmp(results, "")) {// Two Pass的时候走这个函数apply(filter, frame, buffer, format, frequency, channels, samples);} else {// One Pass的时候走这个函数analyze(filter, frame, buffer, format, frequency, channels, samples);}mlt_service_unlock(MLT_FILTER_SERVICE(filter));return 0;
}
analyze:分析得到原音频信息
static void analyze(mlt_filter filter,mlt_frame frame,void **buffer,mlt_audio_format *format,int *frequency,int *channels,int *samples)
{private_data *private = (private_data *) filter->child;mlt_position pos = mlt_filter_get_position(filter, frame);// If any frames are skipped, analysis data will be incomplete.// 作用:确保音频帧按顺序处理,跳过帧会导致分析中断。// 原因:EBU R128 要求连续分析,缺失帧会导致积分响度计算错误。if (private->analyze && pos != private->last_position + 1) {mlt_log_error(MLT_FILTER_SERVICE(filter), "Analysis Failed: Bad frame sequence\n");destroy_analyze_data(filter);}// Analyze Audioif (!private->analyze && pos == 0) {init_analyze_data(filter, *channels, *frequency);}if (private->analyze) {// 作用:将当前音频帧数据(buffer)输入 EBU R128 分析器,更新内部状态。ebur128_add_frames_float(private->analyze->state, *buffer, *samples);if (pos + 1 == mlt_filter_get_length2(filter, frame)) {mlt_properties properties = MLT_FILTER_PROPERTIES(filter);double loudness = 0.0;double range = 0.0;double tmpPeak = 0.0;double peak = 0.0;int i = 0;char result[MAX_RESULT_SIZE];// 计算整体响度ebur128_loudness_global(private->analyze->state, &loudness);// 计算响度范围ebur128_loudness_range(private->analyze->state, &range);// 获取声道峰值for (i = 0; i < *channels; i++) {ebur128_sample_peak(private->analyze->state, i, &tmpPeak);if (tmpPeak > peak) {peak = tmpPeak;}}// 格式化结果并存储snprintf(result, MAX_RESULT_SIZE, "L: %lf\tR: %lf\tP %lf", loudness, range, peak);result[MAX_RESULT_SIZE - 1] = '\0';mlt_log_info(MLT_FILTER_SERVICE(filter), "Stored results: %s\n", result);mlt_properties_set(properties, "results", result);destroy_analyze_data(filter);}private->last_position = pos;}
}
ebur128_gated_loudness: 计算 综合响度(Integrated Loudness)
这段代码是 EBU R128 综合响度(Integrated Loudness) 的核心计算逻辑,用于在音频处理中通过门限控制(Gating)剔除低能量部分,最终得到符合标准的响度值。
static int
ebur128_gated_loudness(ebur128_state** sts, size_t size, double* out) {struct ebur128_dq_entry* it;double gated_loudness = 0.0;double relative_threshold = 0.0;size_t above_thresh_counter = 0;size_t i, j, start_index;// 检查输入的音频状态结构体数组 sts 是否启用了综合响度模式(EBUR128_MODE_I)。若未启用,返回错误。
// 综合响度模式是 EBU R128 的核心功能,需通过 ebur128_init 初始化时设置模式标志for (i = 0; i < size; i++) {if (sts[i] && (sts[i]->mode & EBUR128_MODE_I) != EBUR128_MODE_I) {return EBUR128_ERROR_INVALID_MODE;}}
// 作用:遍历所有音频状态实例,调用 ebur128_calc_relative_threshold 计算 相对门限
// 相对门限:基于音频块能量分布,动态确定一个阈值,剔除低于该值的部分(如静音段或背景噪声)
// 公式:相对门限 = 平均能量 × 相对门限因子(默认-10 dB,即 relative_gate_factor = 0.1)
// 引用:EBU R128 要求综合响度计算需忽略低于动态门限的音频段,以聚焦主要节目内容for (i = 0; i < size; i++) {if (!sts[i]) {continue;}ebur128_calc_relative_threshold(sts[i], &above_thresh_counter,&relative_threshold);}if (!above_thresh_counter) {*out = -HUGE_VAL;return EBUR128_SUCCESS;}relative_threshold /= (double) above_thresh_counter;relative_threshold *= relative_gate_factor;
// 作用:根据相对门限值,确定直方图中高于门限的起始索引 start_index。
// 直方图优化:若启用直方图模式(use_histogram),直接遍历预计算的能量区间,跳过低能量部分。
// 未启用直方图:则需遍历块链表(block_list),逐个检查能量是否高于门限。
// 引用:直方图加速了能量统计,是 EBU R128 实现高效计算的关键优化 above_thresh_counter = 0;if (relative_threshold < histogram_energy_boundaries[0]) {start_index = 0;} else {start_index = find_histogram_index(relative_threshold);if (relative_threshold > histogram_energies[start_index]) {++start_index;}}
// 作用:统计所有高于门限的音频块能量总和 gated_loudness 及其数量 above_thresh_counter。
// 直方图模式:通过预计算的能量值 histogram_energies 和直方图计数快速累加。
// 块链表模式:遍历链表,筛选符合门限的块并累加能量。
// 引用:EBU R128 要求忽略低于门限的音频段,例如静音或低电平背景声for (i = 0; i < size; i++) {if (!sts[i]) {continue;}if (sts[i]->d->use_histogram) {for (j = start_index; j < 1000; ++j) {gated_loudness +=sts[i]->d->block_energy_histogram[j] * histogram_energies[j];above_thresh_counter += sts[i]->d->block_energy_histogram[j];}} else {STAILQ_FOREACH(it, &sts[i]->d->block_list, entries) {if (it->z >= relative_threshold) {++above_thresh_counter;gated_loudness += it->z;}}}}if (!above_thresh_counter) {*out = -HUGE_VAL;return EBUR128_SUCCESS;}
// 作用:
// 平均能量:将累积的能量总和除以有效块数量,得到平均能量。
// 能量转响度:调用 ebur128_energy_to_loudness 将能量转换为 LUFS(Loudness Units Full Scale)。
// 公式:LUFS = 10 × log₁₀(平均能量) - 绝对偏移值(如-0.691 dB,用于校准滤波器响应)
// 引用:LUFS 是 EBU R128 的标准化响度单位,综合响度目标值为 -23 LUFS(广播领域)gated_loudness /= (double) above_thresh_counter;*out = ebur128_energy_to_loudness(gated_loudness);return EBUR128_SUCCESS;
}
ebur128_loudness_range_multiple:计算响度范围(Loudness Range, LRA)
用于衡量音频节目中响度的动态变化
计算多个音频流的综合响度范围(LRA),即节目中最响的 95% 部分与最安静的 10% 部分之间的响度差(单位:LU)
输入:
sts:多个 ebur128_state 状态对象的数组(支持多路音频流合并计算)。
size:数组长度。
输出:
out:计算得到的 LRA 值。
返回值:错误码(成功为 EBUR128_SUCCESS)。
int ebur128_loudness_range_multiple(ebur128_state** sts,size_t size,double* out) {size_t i, j;struct ebur128_dq_entry* it;double* stl_vector;size_t stl_size;double* stl_relgated;size_t stl_relgated_size;double stl_power, stl_integrated;/* High and low percentile energy */double h_en, l_en;int use_histogram = 0;// 模式校验
// 必须启用 LRA 模式:所有状态对象需通过 EBUR128_MODE_LRA 初始化。
// 直方图模式一致性:所有状态对象需统一启用或禁用直方图(EBUR128_MODE_HISTOGRAM)。for (i = 0; i < size; ++i) {if (sts[i]) {if ((sts[i]->mode & EBUR128_MODE_LRA) != EBUR128_MODE_LRA) {return EBUR128_ERROR_INVALID_MODE;}if (i == 0 && sts[i]->mode & EBUR128_MODE_HISTOGRAM) {use_histogram = 1;} else if (use_histogram != !!(sts[i]->mode & EBUR128_MODE_HISTOGRAM)) {return EBUR128_ERROR_INVALID_MODE;}}}
// 直方图模式计算if (use_histogram) {unsigned long hist[1000] = { 0 };size_t percentile_low, percentile_high;size_t index;stl_size = 0;stl_power = 0.0;for (i = 0; i < size; ++i) {if (!sts[i]) {continue;}for (j = 0; j < 1000; ++j) {// 直方图累加:合并所有音频流的短期能量直方图(3秒窗口)。hist[j] += sts[i]->d->short_term_block_energy_histogram[j];stl_size += sts[i]->d->short_term_block_energy_histogram[j];stl_power += sts[i]->d->short_term_block_energy_histogram[j] *histogram_energies[j];}}if (!stl_size) {*out = 0.0;return EBUR128_SUCCESS;}
//门限处理:排除低于平均能量 -20 dB 的块(minus_twenty_decibels = 0.01)。// 平均能量stl_power /= stl_size;// // 应用-20 dB门限stl_integrated = minus_twenty_decibels * stl_power;if (stl_integrated < histogram_energy_boundaries[0]) {index = 0;} else {// 找到门限对应的直方图索引(直方图优化:跳过低于门限的区间,减少计算量。)index = find_histogram_index(stl_integrated);if (stl_integrated > histogram_energies[index]) {++index;}}stl_size = 0;for (j = index; j < 1000; ++j) {stl_size += hist[j];}if (!stl_size) {*out = 0.0;return EBUR128_SUCCESS;}
// 遍历直方图:累加直方图计数,找到对应百分位的能量值。// 10% 低百分位percentile_low = (size_t) ((stl_size - 1) * 0.1 + 0.5);// 95% 高百分位percentile_high = (size_t) ((stl_size - 1) * 0.95 + 0.5);stl_size = 0;j = index;while (stl_size <= percentile_low) {stl_size += hist[j++];}l_en = histogram_energies[j - 1];while (stl_size <= percentile_high) {stl_size += hist[j++];}h_en = histogram_energies[j - 1];
// 计算 LRA(将能量值转换为响度(LU),计算高低百分位的差值*out = ebur128_energy_to_loudness(h_en) - ebur128_energy_to_loudness(l_en);return EBUR128_SUCCESS;}
// 非直方图模式计算同理stl_size = 0;for (i = 0; i < size; ++i) {if (!sts[i]) {continue;}STAILQ_FOREACH(it, &sts[i]->d->short_term_block_list, entries) {++stl_size;}}if (!stl_size) {*out = 0.0;return EBUR128_SUCCESS;}stl_vector = (double*) malloc(stl_size * sizeof(double));if (!stl_vector) {return EBUR128_ERROR_NOMEM;}j = 0;for (i = 0; i < size; ++i) {if (!sts[i]) {continue;}STAILQ_FOREACH(it, &sts[i]->d->short_term_block_list, entries) {stl_vector[j] = it->z;++j;}}qsort(stl_vector, stl_size, sizeof(double), ebur128_double_cmp);stl_power = 0.0;for (i = 0; i < stl_size; ++i) {stl_power += stl_vector[i];}stl_power /= (double) stl_size;stl_integrated = minus_twenty_decibels * stl_power;stl_relgated = stl_vector;stl_relgated_size = stl_size;while (stl_relgated_size > 0 && *stl_relgated < stl_integrated) {++stl_relgated;--stl_relgated_size;}if (stl_relgated_size) {h_en = stl_relgated[(size_t) ((stl_relgated_size - 1) * 0.95 + 0.5)];l_en = stl_relgated[(size_t) ((stl_relgated_size - 1) * 0.1 + 0.5)];free(stl_vector);*out = ebur128_energy_to_loudness(h_en) - ebur128_energy_to_loudness(l_en);} else {free(stl_vector);*out = 0.0;}return EBUR128_SUCCESS;
}
ebur128_sample_peak:获取指定声道采样峰值(Sample Peak)
作用:获取音频流中指定声道的采样峰值电平(单位:dBFS)。
采样峰值(Sample Peak):音频信号在数字域中的最大绝对值,未经插值处理,直接来自采样点。
用途:检测音频是否削波(超过 0 dBFS),确保符合广播或流媒体的响度标准。
int ebur128_sample_peak(ebur128_state* st,unsigned int channel_number,double* out) {if ((st->mode & EBUR128_MODE_SAMPLE_PEAK) != EBUR128_MODE_SAMPLE_PEAK) {return EBUR128_ERROR_INVALID_MODE;}if (channel_number >= st->channels) {return EBUR128_ERROR_INVALID_CHANNEL_INDEX;}*out = st->d->sample_peak[channel_number];return EBUR128_SUCCESS;
}
apply
核心目标:将音频的响度调整到用户设定的目标值(如 EBU R128 规定的 -23 LUFS)。
输入依赖:需要预先通过分析阶段获取当前音频的响度(in_loudness)、响度范围(in_range)和峰值(in_peak)。
操作:计算增益系数并应用到音频数据,使其响度匹配目标值。
static void apply(mlt_filter filter,mlt_frame frame,void **buffer,mlt_audio_format *format,int *frequency,int *channels,int *samples)
{mlt_properties properties = MLT_FILTER_PROPERTIES(filter);char *results = mlt_properties_get(properties, "results");double in_loudness;double in_range;double in_peak;int scan_return = sscanf(results, "L: %lf\tR: %lf\tP %lf", &in_loudness, &in_range, &in_peak);if (scan_return != 3) {mlt_log_error(MLT_FILTER_SERVICE(filter), "Unable to load results: %s\n", results);} else {// 计算增益系数// 增益公式是固定的double target_db = mlt_properties_get_double(properties, "program");double delta_db = target_db - in_loudness;double coeff = delta_db > -90.0 ? pow(10.0, delta_db / 20.0) : 0.0;float *p = *buffer;int count = *samples * *channels;// 线性增益:将每个音频样本乘以计算出的增益系数。// 声道处理:遍历所有声道和样本,统一应用增益。for (int i = 0; i < count; i++) {p[i] = p[i] * coeff;}}
}
相关文章:
MLT媒体程序框架03:滤镜——loudness
EBU R.128协议 引用链接 EBU的全称为European Broadcasting Union ,既欧洲广播联盟,为欧洲与北非各广播业者(包含广播电台与电视台)的合作组织,成立于1950年2月12日,有五十多个正式加盟国,总部位于瑞士日内瓦,目前中国…...
FreeRTOS第15篇:FreeRTOS链表实现细节03_List_t与ListItem_t的奥秘
文/指尖动听知识库-星愿 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:深入FreeRTOS内核:从原理到实战的嵌入式开发指南 1 FreeRTOS列表的核心数据结构 FreeRTOS的列表实现由两个关键结构体组成:List_t(列表)和ListItem_t(列表项)。它们共同…...
Spring Boot静态资源访问顺序
在 Spring Boot 中,static 和 public 目录都用于存放静态资源(如 HTML、CSS、JavaScript、图片等文件),但它们在使用上有一些细微的区别。以下是它们的详细对比: 1. 默认优先级 Spring Boot 会按照以下优先级加载静态…...
什么是 spring 的循环依赖?
什么是 spring 的循环依赖? 首先,认识一下什么是循环依赖,举个例子:A 对象被 Spring 管理,并且引入的 B 对象,同样的 B 对象也被 Spring 管理,并且也引入的 A 对象。这种相互被引用的情况&#…...
RSA的理解运用与Pycharm组装Cryptodome库
1、RSA的来源 RSA通常指基于RSA算法的密码系统,令我没想到的是,其名字的来源竟然不是某个含有特别意义的单词缩写而成(比如PHP:Hypertext Preprocessor(超文本预处理器)),而是由1977年提出该算法的三个歪果…...
AI数据分析:deepseek生成SQL
在当今数据驱动的时代,数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展,AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行自动补全SQL 查询语句。 我们都知道,SQL 查询语…...
git的坑
不小心把工作区的代码全删掉了 首先是名字出错,不知为何gitee任意把我的名字更改。 导致无法push验证 git push -u origin "master 显示:fatal: Authentication failed for https://gitee.com/zhang-great/stm32-smart-security-system.git/ 我…...
小程序事件系统 —— 32 事件系统 - 事件分类以及阻止事件冒泡
在微信小程序中,事件分为 冒泡事件 和 非冒泡事件 : 冒泡事件:当一个组件的事件被触发后,该事件会向父节点传递;(如果父节点中也绑定了一个事件,父节点事件也会被触发,也就是说子组…...
PLC数据类型和C#数据类型的数据类型映射表
数据类型映射表 PLC数据类型C#数据类型读取方式补充说明BitboolDBX布尔值BytebyteDBB单字节无符号整数WordushortDBW16位无符号整数DWorduintDBD32位无符号整数Intshort16位有符号整数DIntint32位有符号整数RealfloatDBR单精度浮点数LRealdoubleDBL双精度浮点数Stringstr…...
全球首创!微软发布医疗AI助手,终结手写病历时代
今天凌晨,微软发布了医疗界首个用于临床工作流程的AI助手Microsoft Dragon Copilot。 Dragon Copilot是基于语音文本的混合架构,能够将医生的语音或临床口述内容实时转换为文本。例如,医生可以通过语音输入患者的病历信息、医嘱或诊断结果&a…...
每日一题----------异常处理
总结: NullPointerException:尝试使用一个空引用进行操作时抛出。 ArrayIndexOutOfBoundsException:数组下标越界时抛出。 ClassCastException:类型转换失败时抛出。 ArithmeticException:数学运算错误时抛出&#…...
HTML 属性(详细易懂)
HTML(超文本标记语言)是用于创建网页和其他可在浏览器中查看的内容的基础标记语言。HTML 属性是 HTML 元素的额外信息,它们提供了元素的更多细节,如元素的标识符、样式、行为等。在本文中,将详细介绍 HTML 属性&#x…...
基于火山引擎的DeepSeek-V3 api实现简单的数据查询功能
前言 现在ai比较火,ai可以极大的提高大家的工作效率,所以有空的话要学习下ai的使用 火山引擎大模型 火山引擎大模型广场,聚集了市面上常见的基座大模型,每个模型都有50Wtokens的免费调用量,可以方便大家调用 账号登…...
AI入门1:关键概念
1. 基础概念 AI(Artificial Intelligence,人工智能) 模拟人类智能的机器系统,具备学习、推理、决策等能力。 Machine Learning(机器学习,ML) 让计算机通过数据自动学习规律,…...
WPS工具栏添加Mathtype加载项
问题描述: 分别安装好WPS和MathType之后,WPS工具栏没直接显示MathType工具,或者是前期使用正常,由于WPS更新之后MathType工具消失,如下图 解决办法 将文件“MathType Commands 2016.dotm”和“MathPage.wll”从Matht…...
【MySQL-数据类型】数据类型分类+数值类型+文本、二进制类型+String类型
一、数据类型分类 二、数值类型 1.bit类型 测试环境ubuntu 基本语法: bit[(M)]:位字段类型,M表示每个值的位数,范围从1~64;如果M被忽略,默认为1举例: create table testBit(id i…...
cuda矩阵转置算子(共享内存)
cpu版本 即为按行遍历行列互换 // 主机上的矩阵转置函数,用于验证结果 void cpuTranspose(const float *input, float *output, int n) {for (int row 0; row < n; row){for (int col 0; col < n; col){output[col * n row] input[row * n col];}} }gp…...
GB28181视频监控流媒体平台LiveGBS如何自定义收流端口区间以便减少收流端口数或解决端口冲突问题
LiveGBS GB28181流媒体服务在接收视频的时候默认是使用30000-30249, webrtc流播放端口区间默认是UDP的30250-30500区间。有些网络环境不方便开放这么大的端口区间,下面介绍下如何修改配置这个区间。 从页面上修改这个区间,端口区间尽量设置大…...
在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法总结
在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法因数据类型而异。以下是各类型变量的判断方法总结: 1. 基本类型 整数(int) 判断是否等于零值 0。 var i int if i == 0 { // 空 } 字符串(string) 判断是否等于空字符串 ""。 var s string if s =…...
VUE3开发-9、axios前后端跨域问题解决方案
VUE前端解决跨域问题 前端页面需要改写 如果无效,记得重启服务器 后端c#解决跨域问题 前端js取值,后端c#跨域_c# js跨域-CSDN博客...
利用 requestrepo 工具验证 XML外部实体注入漏洞
1. 前言 在数字化浪潮席卷的当下,网络安全的重要性愈发凸显。应用程序在便捷生活与工作的同时,也可能暗藏安全风险。XXE(XML外部实体)漏洞作为其中的典型代表,攻击者一旦利用它,便能窃取敏感信息、掌控服务…...
嵌入式开发之串行数据处理
前题 前面几篇文章写了关于嵌入式软件开发时,关于串行数据处理的一些相关内容,有兴趣的可以看看《嵌入式开发:软件架构、驱动开发与串行数据处理》、《嵌入式软件开发之生产关系模型》和《嵌入式开发之Modbus-RTU协议解析》相关的内容。从业十…...
深入解析 JVM —— 从基础概念到实战调优的全链路学习指南
文章目录 一、为什么要学习 JVM?1. 面试必备与技能提升2. 性能优化与问题诊断3. 编写高质量代码 二、JVM 基础概念与体系结构1. JVM 简介2. JDK、JRE 与 JVM 三、JVM 内存模型1. 线程私有区2. 线程共享区 四、类加载机制与双亲委派1. 类加载过程2. 双亲委派模型3. 动…...
LTC6804、LTC6811、LTC6813的使用
FSEC自制BMS第一步:从零开发使用LTC6804采集电池电压 LTC6811特性 LTC6811 是 LTC6804 的引脚兼容型升级器件,LTC6804官方已经不推荐选用 可测量多达 12 节串联电池 1.2mV 最大总测量误差 可堆叠式架构能支持几百个电池 内置 isoSPI™ 接口 可在 290μ…...
Spring 构造器注入和setter注入的比较
一、比较说明 在 Spring 框架中,构造器注入(Constructor Injection)和 Setter 注入(Setter Injection)是实现依赖注入(DI)的两种主要方式。它们的核心区别在于依赖注入的时机、代码设计理念以及…...
【LangChain】对话历史管理
1 历史记录的剪裁 trimmed_messages from langchain_core.messages import (AIMessage,HumanMessage,SystemMessage,trim_messages, ) from langchain_openai import ChatOpenAImessages [SystemMessage("youre a good assistant, you always respond with a joke."…...
【无人机三维路径规划】基于CPO冠豪猪优化算法的无人机三维路径规划Maltab
代码获取基于CPO冠豪猪优化算法的无人机三维路径规划Maltab 基于CPO冠豪猪优化算法的无人机三维路径规划 一、CPO算法的基本原理与核心优势 冠豪猪优化算法(Crested Porcupine Optimizer, CPO)是一种新型元启发式算法,其灵感来源于冠豪猪的…...
CAN协议介绍
目录 一、CAN协议 1.1 CAN协议简介 1.2 CAN物理层 1.3 CAN协议层 二、CAN控制器 2.1 CAN控制内核 2.2 CAN发送邮箱 2.3 CAN接收FIFO 2.4 CAN验收筛选器 一、CAN协议 1.1 CAN协议简介 CAN 是控制器局域网络 (Controller Area Network) 的简称,它是由研发和生…...
树莓派 Interface Option 中没有camera选项
最近重温树莓派的视觉,烧录了树莓派的新系统后发现在 raspi-config 中的 Interface Option 没有 camera 选项,同时在终端用 vcgencmd get_camera 查看摄像头时没有检测到树莓派的 CSI 摄像头,在 Thonny 中调用树莓派摄像头出现报错࿱…...
大数据学习(55)-BI工具数据分析的使用
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
轻松上手 —— 通过 RPM 包快速部署 NebulaGraph
前言 在当今大数据时代,处理复杂关系数据的需求与日俱增,图数据库应运而生并逐渐崭露头角。NebulaGraph 作为一款高性能、分布式且易扩展的图数据库,专为应对大规模图数据处理而精心打造。它不仅具备丰富的查询语言,还拥有强大高效…...
nginx作为下载服务器配置
一、Nginx 作为下载服务器配置笔记 基本配置指令 server块配置: 在 Nginx 的配置文件(通常是/etc/nginx/nginx.conf或在/etc/nginx/conf.d/目录下的特定配置文件)中,首先需要定义一个server块来监听特定的端口并处理下载请求。例如…...
第六课:数据存储三剑客:CSV/JSON/MySQL
在Python的数据存储与处理领域,CSV、JSON和MySQL被广大开发者誉为“数据存储三剑客”。它们各自在不同的场景下发挥着重要作用,无论是简单的数据交换、轻量级的数据存储,还是复杂的关系型数据库管理,都能找到它们的身影。本文将详…...
Dify 开源大语言模型应用开发平台使用(一)
文章目录 一、创建锂电池专业知识解答应用1.1 应用初始化二、核心功能模块详解2.1 知识库构建2.2 工作流与节点编排节点类型说明工作流设计示例:锂电池选型咨询2.3 变量管理三、测试与调试3.1 单元测试3.2 压力测试3.3 安全验证四、部署与优化建议4.1 部署配置4.2 持续优化结论…...
PyQt高亮代码
PyQt高亮代码 安装 Pygments支持的格式支持的样式详解参考 Qt中使用 安装 Pygments Pygments 是Python中的一个高亮代码的包,挺好用的 pip install Pygments支持的格式 支持的格式比较多,不列出来了 # coding:utf-8 from pygments.lexers import get_all…...
小白学Agent技术[1]
文章目录 课程地址Agent介绍原理架构任务规划记忆工具使用程序开发范式的变化Agent开发注意事项 课程地址 Agent课程地址 Agent介绍 AI Agent(人工智能代理、AI智能体),一种模拟人类智能行为的人工智能系统,以大模型语言&#…...
以商业思维框架为帆,驭创业浪潮前行
创业者踏入商海,如同航海家奔赴未知海域,需有清晰的思维罗盘指引方向。图中“为什么—用什么—怎么做—何人做—投入产出”的商业框架,正是创业者破解商业谜题的密钥,从需求洞察到落地执行,为创业之路铺就逻辑基石。 …...
开源宝藏 Tigshop,开启电商新征程
在电商竞争愈发激烈的当下,一个强大且适配的商城系统是商家制胜的法宝。 Tigshop官网:Tigshop官网 - 开源商城系统Tigshop开源商城系统,支持b2b2c、多商户、多店铺、商家入驻、分销系统、跨境电商、连锁商城等解决方案,免费下载&…...
java多线程实现方式
目录 1. 继承 Thread 类 2. 实现 Runnable 接口 3. 实现 Callable 接口 4. 使用线程池 5. 使用 CompletableFuture(Java 8) 6. 使用 ForkJoinPool(Java 7) 7. 使用 Timer 和 TimerTask 8. 使用 ScheduledExecutorService …...
windows:curl: (60) schannel: SEC_E_UNTRUSTED_ROOT (0x80090325)
目录 1. git update-git-for-windows 报错2. 解决方案2.1. 更新 CA 证书库2.2. 使用 SSH 连接(推荐)2.3 禁用 SSL 验证(不推荐) 1. git update-git-for-windows 报错 LenovoLAPTOP-EQKBL89E MINGW64 /d/YHProjects/omni-channel-…...
python:pymunk + pygame 模拟六边形内小球弹跳运动
向 chat.deepseek.com 提问:编写 python 程序,用 pymunk, 有一个正六边形,围绕中心点缓慢旋转,六边形内有一个小球,六边形的6条边作为墙壁,小球受重力和摩擦力、弹力影响,模拟小球弹跳运动&…...
vulnhub靶场之【digitalworld.local系列】的vengeance靶机
前言 靶机:digitalworld.local-vengeance,IP地址为192.168.10.10 攻击:kali,IP地址为192.168.10.6 kali采用VMware虚拟机,靶机选择使用VMware打开文件,都选择桥接网络 这里官方给的有两种方式ÿ…...
shiro550-cve-2016-4437复现
shiro550-cve-2016-4437 复现环境:docker desktop idea远程调试jdk版本必须与容器里的jdk1.8.0_102 匹配上,下载资源翻我CC1链那篇文章 注意burpsuite的proxy listeners端口改一下别跟docker容器的重了。 ysoserial工具:https://github.c…...
【DeepSeek】Ubuntu快速部署DeepSeek(Ollama方式)
文章目录 人人都该学习的DeepSeekDeepSeek不同版本功能差异DeepSeek与硬件直接的关系DeepSeek系统兼容性部署方式选择部署步骤(Ollama方式)1.选定适合的deepseek版本2.环境准备3.安装Ollama4.部署deepseek5.测试使用 人人都该学习的DeepSeek DeepSeek 作…...
Windows 版本Nmap使用报错“无法打开device eth0”
背景 使用nmap在win10上进行扫描工作正常,换到win server 2012 r2以后,扫描报错“无法打开device eth0” 使用了重装、重启大法,未彻底解决 PS:这台服务器之前完装过wireshark,实际已经安装了npcap 解决步骤 查询了…...
java字符串
字符串构造 1.使用常量串构造 String h1 "hello";System.out.println(h1); 2.new对象 String h2 new String("hello");System.out.println(h2); 3.使用字符数组构造 char[] array {h,e,l,l,o};String h3 new String(array);System.out.println(h3);…...
Uniapp 页面返回不刷新?两种方法防止 onShow 触发多次请求!
目录 前言1. 变量(不生效)2. 延迟(生效) 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 在 Uniapp 中,使用 onShow() 钩子来监听页面显示࿰…...
鸿蒙生态日日新,夸克、顺丰速运、驾校一点通等多款应用功能更新
3月5日鸿蒙生态日日新PLOG:吉事办、健康甘肃等政务服务App上架原生鸿蒙应用市场;夸克、顺丰速运、驾校一点通等多款应用功能更新。...
库制作与原理
什么是库 库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入…...
《量子Java:从超导芯片到光子计算的编程革命》——解析Google量子AI中心的混合架构,揭秘如何用Java控制量子比特!
标题:《量子Java:从超导芯片到光子计算的编程革命》——解析Google量子AI中心的混合架构,揭秘如何用Java控制量子比特! 引言:当Java代码撞上量子叠加态——Google量子AI中心的0.003秒奇迹 Google量子AI中心首次实现Java程序对1200量子比特光量子芯片的实时控制,仅耗时3毫…...