完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>
标签 > LPC
LPC是线性预测编码是一种非常重要的编码方法。从原理上讲,LPC是通过分析话音波形来产生声道激励和转移函数的参数,对声音波形的编码实际就转化为对这些参数的编码,这就使声音的数据量大大减少。
LPC是线性预测编码(linear predictive coding,LPC)是一种非常重要的编码方法。从原理上讲,LPC是通过分析话音波形来产生声道激励和转移函数的参数,对声音波形的编码实际就转化为对这些参数的编码,这就使声音的数据量大大减少。在接收端使用LPC分析得到的参数,通过话音合成器重构话音。合成器实际上是一个离散的随时间变化的时变线性滤波器,它代表人的话音生成系统模型。时变线性滤波器既当作预测器使用,又当作合成器使用。分析话音波形时,主要是当作预测器使用,合成话音时当作话音生成模型使用。随着话音波形的变化,周期性地使模型的参数和激励条件适合新的要求。
LPC是线性预测编码(linear predictive coding,LPC)是一种非常重要的编码方法。从原理上讲,LPC是通过分析话音波形来产生声道激励和转移函数的参数,对声音波形的编码实际就转化为对这些参数的编码,这就使声音的数据量大大减少。在接收端使用LPC分析得到的参数,通过话音合成器重构话音。合成器实际上是一个离散的随时间变化的时变线性滤波器,它代表人的话音生成系统模型。时变线性滤波器既当作预测器使用,又当作合成器使用。分析话音波形时,主要是当作预测器使用,合成话音时当作话音生成模型使用。随着话音波形的变化,周期性地使模型的参数和激励条件适合新的要求。
LPC学习笔记
从lpc-tutorial下载tutorial,通过阅读教程来学习LPC。
关于LPC
LPC被发明出来是一个用于LPMUD的解释性语言。LPMUD其实就是一个游戏服务器,那么就很清楚了LPC是一个用来写游戏服务器的脚本语言。
LPC这个名字暗示了和C语言的联系。当然两者之间是有区别的,后面会渐次展开来讲。
LPC游戏解析
一个LPC游戏可以划分为三个部分:游戏驱动、mudlib、domain code。
游戏驱动:运行于主机上的程序。基本的对象管理核心和解释器。它被用来理解LPC语言并执行这些指令。
mudlib:LPC对象的集合。其中包含了基本的游戏环境。mulib里面的对象是最基本的游戏元素,比如玩家、怪物、房子等等。
domain code:???
语法入门
啥都别说了,看代码。
while语句
while (test)
statement;
if语句
if (this)
{
statement;
}
else if (that)
{
another_statement;
}
else
{
default_statement;
}
定义变量
int a, b, c;
for循环:
for (a = 0; a 《 10; a++)
{
b = function_call(a, b * 2);
c = b * 3 / 4;
}
空语句循环:
while (!(var = func(var)))
;
for循环:
for (i = 0; i 《 100; i++);
{
《code that gets executed only once, but always》
}
定义方法:
public void
my_function(int a, int b)
{
《 code 》
}
文件头注释:
/*
* 《filename》
*
* 《Short description of what the file does, no more than 5-7 lines.
* 。。.
* 。。. 》
*
* Copyright (C): 《your name and year》
*
*/
函数注释:
/*
*
*
* Arguments: 《A list of all arguments, one per line
* arg1 - description no longer than the line.
* arg2 - next argument, etc. 》
* Returns: 《What the function returns》
*/
LPC基本语言概念
LPC不是编译型的,而是解释型的语言。
每次运行都被会重新解释为机器语言。
其实这意味我们写的是一种间接语言,通过特定的解释器执行特定的机器语言。
LPC语言的文件都是以.c为后缀的。文件名全部小写,如果文件里面含有多个单词,用下划线_把单词隔开。
LPC基本语法
注释
// This is a comment stretching to the end of the line.
/* This is an enclosed comment */
数据类型
void:nothing
int:the range -2147483648 to 2147483647.
float:range 1.17549435e-38 to 3.40282347e+38.
string:such as “hallo world!”
mapping:key value pair.
object:references to LPC programs loaded into memory.
function:LPC functions.
array:all of things
mixed:all of type
变量声明
int counter;
float height, weight;
mapping age_map;
int counter = 8;
float height = 3.0, weight = 1.2;
mapping age_map = ([]);
object *monsters = ({});
基本上语法和pike是差不多的,如果还没入门最好先去看看pike。pike学习笔记
如果没有为变量赋初值,那么变量会被赋值为0,相当于其他语言的null,一般来说都不是我们希望看到的,所以哪怕赋值为空都好过没有。
方法声明
/*
* Compute the diameter of a circle given the circumference.
*
* Variables: surf_area - the surface area
* name - the name given the circle
* Returns: The circumference.
*/
float
compute_diam(float surf_area, string name)
{
float rval;
// Circumference = pie * diameter
rval = surf_area / 3.141592643;
write(“The diameter of ” + name + “ is ” + ftoa(rval) + “\n”);
return rval;
}
基本上对照上面的例子就知道怎么去声明和定义一个方法了。
语句和表达式
就是一些算数、布尔、条件、比较操作符。跟pike差不多,不赘述了。
比较特别的是:
The statement ‘a = 1, 2, 3;’ will set ‘a’ to contain ‘1’。
一般我们写if语句都这样写:
if (name == “fatty”)
{
nat = “se”;
desc = “blimp”;
}
else if (name == “plugh”)
{
nat = “no”;
desc = “warlock”;
}
else if (name == “olorin”)
{
nat = “de”;
desc = “bloodshot”;
}
else
{
nat = “x”;
desc = “unknown”;
}
更好的选择其实是使用switch语句:
switch (name)
{
case “fatty”:
nat = “se”;
desc = “blimp”;
break;
case “plugh”:
nat = “no”;
desc = “warlock”;
break;
case “olorin”:
nat = “de”;
desc = “bloodshot”;
break;
default:
nat = “x”;
desc = “unknown”;
}
省了很多括号,而且更加清晰明了。
多用三元符号代替if-else语句:
int max(int a, int b)
{
if(a 》 b)
return a;
else
return b;
}
int max(int a, int b)
{
a 》 b ? a:b;
}
优先级可以去查表:lpc优先级查找
普通的循环语句就不再赘述了。
array
可以通过下面的方式声明array:
int *my_arr, *your_arr;
float *another_arr;
object *ob_arr;
my_arr = ({})
虽然我觉得这种方式不太好。
可以声明一个固定大小的array:
you_arr = allocate(3); // =》 your_arr = ({ 0, 0, 0 });
此外,如何想要在array后面或者前面添加元素,可以这样:
int a = 3;
int *b = ({1,2});
b = b + ({a});
甚至还能切片,切片始终返回一个array:
my_arr = ({ 9, 3, 5, 10, 3 });
my_arr = my_arr[0..0] + my_arr[2..4]; // =》 ({ 9, 5, 10, 3 })
mapping
mapping就是键值对序列。
声明一个mapping:
mapping my_map;
使用mapping的方法和pike一致。
比较特别的是,如果想删除mapping内的数据,可以用这个:
my_map = m_delete(my_map, “bertil”);
my_map = m_delete(my_map, “david”);
此外,如果查找一个不存在的键值对,不会报错,而是返回0.
预处理
预处理并不属于LPC语言的一部分。在编译为可执行程序之前,预处理会将替换好所有的特定字符串。
导入源文件
当我们需要一些其他源代码文件提供的函数时,我们可以通过下面的方式来导入:
#include 《standard_file》
#include “special_file”
#include 《stdproperties.h》
#include 《adverbs.h》
#include “/d/Genesis/login/login.h”
#include “my_defs.h”
#include “/sys/adverbs.h” // Same as the shorter one above
基本上和C语言导入源文件是一样的。
宏定义
偶尔我们会需要用字符串来代替数字或者表达式,比如说:
#define MAX_LOGIN 100 /* Max logged on players */
#define LOGIN_OB “/std/login” /* The login object */
#define GREET_TEXT “Welcome!” /* The login message */
一般来说,不建议写宏。因为宏是无类型的,而且会在异常时无法确定到底是哪个地方出了问题。建议使用常量来代替宏,记得宏之所以还存在完全是为了向下兼容。
#if, #ifdef, #ifndef, #else and #elseif
直接看代码吧:
#if CODE_VAR == 2
《code that will be kept only if CODE_VAR == 2》
#else
《code that will be kept only if CODE_VAR != 2》
#endif
#define CODE_VAR /* This defines the existence of CODE_VAR */
#ifdef CODE_VAR
《code that will be kept only if CODE_VAR is defined》
#else
《code that will be kept only if CODE_VAR isn‘t defined》
#endif
#ifndef CODE_VAR
《code that will be kept only if CODE_VAR isn’t defined》
#else
《code that will be kept only if CODE_VAR is defined》
#endif
感觉用这些有硬编码的感觉,会增加理解代码的难度,所以不推荐使用。
进阶篇
打印
1、write:自然不用在赘述了,相当于printf。
2、dump_array:打印一个array所有值,调试的时候挺有用的。注意,pike里没有这个函数。
函数调用
各种外部函数调用方式:
pie = math_ob-》compute_pie(1.0);
pie = “/d/Mydom/thewiz/math_ob”-》compute_pie(1.0);
pie = call_other(math_ob, “compute_pie”, 1.0);
pie = call_other(“/d/Mydom/thewiz/math_ob”, “compute_pie”, 1.0);
虽然后面三种也能调用函数,但是这种代码的可读性太低了,完全应该忘掉。
再来看看实际应用时的情况:
object *people, *names;
mapping hp_map;
// Get a list of all players.
people = users();
// Get their names.
names = people-》query_real_name();
// Make a mapping to call with. Item = name:pointer
hp_map = mkmapping(names, people)
// Replace the pointers with hit point values.
hp_map = hp_map-》query_hp();
// All this could also have been done simpler as:
hp_map = mkmapping(users()-》query_real_name(), users()-》query_hp());
如何继承一个对象类?
inherit “《file path》”;
// 比如说
inherit “/std/door”;
inherit “/std/room.c”;
//栗子
void
my_func()
{
/*
* This function exists in the parent, and I need to
* call it from here.
*/
::my_func(); // Call my_func() in the parent.
}
检测变量类型
由于变量可能是0或者任意类型的东西,往往需要自己对变量做类型检查。
@bullet{int intp(mixed)}
Test if given value is an integer
@bullet{int floatp(mixed)}
Test if given value is a float
@bullet{functionp(mixed)}
Test if given value is a function pointer
@bullet{int stringp(mixed)}
Test if given value is a string
@bullet{int objectp(mixed)}
Test if given value is an object pointer
@bullet{int mappingp(mixed)}
Test if given value is a mapping
@bullet{int pointerp(mixed)}
Test if given value is an array
类型限定符
static 变量:静态的全局变量,声明一次之后一直存在
static 函数:只能内部访问,外部是不可见的
private 变量或函数:不被继承,只能对象内部访问
normal 变量或函数:can not be mask?
public 变量或函数:默认的限定符,任何成员都可访问内部对象
varargs 函数:可变参数数量的,按顺序对参数赋值,如果没有则默认赋值为0。
函数类型
函数也可以作为一个变量。
function my_func, *func_array;
my_func = allocate;
my_func = &allocate();
int *i_arr;
i_arr = allocate(5); // Is the same as.。。
i_arr = my_func(5); // 。。. using the function assignment above.
通过这种方式给函数重命名。
switch case
LPC的switch case支持int范围:
switch (i)
{
case 0..4:
write(“Try again, sucker!\n”);
break;
case 5..6:
write(“Congrats, third prize!\n”);
break;
case 7..8:
write(“Yes! Second prize!\n”);
break;
case 9:
write(“WOOOOPS! You did it!\n”);
break;
default:
write(“Someone has tinkered with the wheel.。。 Call 911!\n”);
break;
}
catch throw
LPC和普通语言的try-catch方式捕获异常是不一样的:
int catch(function)
e.g.
//0-fail 1-true
if (catch(tail(“/d/Relic/fatty/hidden_donut_map”)))
{
write(“Sorry, not possible to read that file.\n”);
return;
}
throw(mixed info)
e.g.
if (test 《 5)
throw(“The variable ‘test’ is less than 5\n”);
mapping、array 引用
LPC的mapping、array与pike一样是引用类型:
object *arr, *copy_arr;
arr = ({ 1, 2, 3, 4 }); // An array
copy_arr = arr; // Assume (wrongly) that a copy_arr becomes
// a copy of arr.
// Change the first value (1) into 5.
copy_arr[0] = 5;
//如果想要一份拷贝怎么做?
copy_arr = ({ }) + arr;
LPC/Mudlib接口
感觉到这里就是要开始学习如何实际使用LPC来编程了。前面的都只是基本的语法知识。
首先介绍:/std/object.c。游戏里所有的对象都会继承这个基本类型。
其他类型有:
`/std/armour.c‘
Armour of any kind
`/std/board.c’
Bulletin boards
`/std/book.c‘
A book with pages you can open, turn and read
`/std/coins.c’
The base of all kinds of money
`/std/container.c‘
Any object that can contain another
`/std/corpse.c’
Corpse of dead monsters/players/npcs
`/std/creature.c‘
Simple living creatures, basically a mobile that can fight
`/std/domain_link.c’
Use this as a base to preload things in domains
`/std/door.c‘
A door that connects two rooms
`/std/drink.c’
Any type of drink
`/std/food.c‘
Any type of food
`/std/guild (directory)’
Guild related objects (the guild and the shadows)
`/std/heap.c‘
Any kind of object that can be put in heaps
`/std/herb.c’
Herbs
`/std/key.c‘
Keys for doors
`/std/leftover.c’
Remains from decayed corpses
`/std/living.c‘
Living objects
`/std/mobile.c’
Mobile living objects
`/std/monster.c‘
Monsters of any kind
`/std/npc.c’
A creature which can use ‘tools’, i.e. weapons.
`/std/object.c‘
The base object class
`/std/poison_effect.c’
Handle effects in poison of any kind
`/std/potion.c‘
Potions
`/std/receptacle.c’
Any kind of closable/lockable container
`/std/resistance.c‘
Handle resistance against various kinds of things
`/std/room.c’
Any kind of room
`/std/rope.c‘
Rope objects
`/std/scroll.c’
Scrolls
`/std/shadow.c‘
Used as base when creating shadows
`/std/spells.c’
Spell objects, tomes etc
`/std/torch.c‘
Torches/lamps etc
`/std/weapon.c’
Any kind of weapons
对象的使用
一个对象总是能够得到自己的引用:
ob = this_object()
这个就类似于C++的this指针。
对象的函数能够往前去查找调用此函数的对象(好神奇的感觉):
p_ob = previous_object(); // The object calling this function.
pp_ob = previous_object(-2); // The object calling the object
// calling this function.
甚至还能往前找指定层数的对象。
不过这个函数只能去找外部调用,如果我们想要更牛掰的话,用这个:
object calling_object(void|int step)
用法是一样的,但是能够找内部也能找外部。
怎么去判断找到的是一个合法的东西呢?(不是一个0)用objectp(something)就好了:
if (objectp(calling_object(-2)))
write(“Yes, an ob calling an ob calling this object exists!\n”);
else
write(“No such luck.\n”);
函数类型
在LPC里面,函数function也是一种对象,或者说变量类型。
可以像这样定义一个函数指针:
function f = (: local_func :);
上面的 f 可以用于其他程序流程或外部函数中, 如同普通的变量值:
foo(f); map_array( ({ 1, 2 }), f);
或者可以直接执行:
x = evaluate(f, “hi”);
等同于:
x = local_func(“hi”);
甚至于,定义函数指针时还能指定参数:
function f = (: write, “Hello, world!\n” :);
evaluate(f);
显然,会输出:
Hello, world!
如果想要调用外部对象的函数:
f = (: this_player(), ({ “query”, “short” }) :)
等同于:
f = (: call_other, this_player(), “query”, “short” :) /* 一个外部函数指针, 使用 call_other */
f = (: this_player()-》query(“short”) :) // 有效的运算式; 请见下文。
特殊的,运算式函数指针:
evaluate( (: $1 + $2 :), 3, 4) // 返回 7.
这可以用于 sort_array, 范例如下:
top_ten = sort_array( player_list,(: $2-》query_level() - $1-》query_level :) )[0..9];
不知名函数(函数内部的函数):
void create() {
function f = function(int x) {
int y;
switch(x) {
case 1: y = 3;
case 2: y = 5;
}
return y - 2;
};
printf(“%i %i %i\n”, (*f)(1), (*f)(2), (*f)(3));
}作者:1angxi链接:http://www.jianshu.com/p/11a5a2afbf86來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Phoenix Contact 用于电子应用的 LPC 2,5 PCB 连接器
作者:Rolf Horn 投稿人:DigiKey 欧洲编辑 PCB 连接器是一种模块化的绝缘装置,可用于电路板的电气连接。随着对紧凑型高效电子设备需求的...
在使用 lpc55s69_nxp_evk 开发板对接 rtduino 的过程,对接 PWM 部分的时候,遇到了不少坑,在此记录。
在使用 RT-Thread 的 bsp pwm 的时候,注意到 lpc55sxx 系列只对接了通用定时器2中的通道1作为 PWM 输出。但其实 LPC5...
v4.0 版本新增了不少新型号的支持,囊括经典的 i.MXRT、LPC 系列以及全新的 MCX 系列下最近发布的产品。
随着超大规模集成电路的不断发展,芯片的功能也愈发集中,在电子产品的系统中 “各司其职” 。在一个电子产品的硬件系统中,通常都是多个芯片协同工作,所以芯片...
英诺达发布了自主研发的EnFortius®凝锋®RTL级功耗分析工具,可以在IC设计流程早期对电路设计进行优化。
英诺达发布了自主研发的静态验证EDA工具EnAltius®昂屹® DFT Checker,该工具可以在设计的早期阶段发现与DFT相关的问题或设计缺陷。
全功能双CameraLink SDR接口 FMC子卡QT7421介绍
QT7421是一款具有2个Camera Link SDR接口的全功能单宽FMC子卡模块,它提供标准的工业相机链路接口,为用户提供了利用FPGA解决大运算...
关于2023赛季RoboMaster机甲大师赛机器人用导电滑环
新赛季RoboMaster机甲大师赛即将打响,由于新赛季比赛规则发生了一些变更,所以参赛战队也不得不更新一部分机器人,英雄机器人、哨兵机器人、步兵机器人...
项目中源文件(*.c)和头文件(*.h)的总数较多。因此,我们只详细介绍关键项目文件,其余的将被分组描述。
在所有的滑环类型中,只有高频滑环具备高清视频信号和高频信号传输的能力,当然,这两种信号不能同时在一个高频滑环内传输。通常情况下,用以传输高清视频信号的高...
编辑推荐厂商产品技术软件/工具OS/语言教程专题
电机控制 | DSP | 氮化镓 | 功率放大器 | ChatGPT | 自动驾驶 | TI | 瑞萨电子 |
BLDC | PLC | 碳化硅 | 二极管 | OpenAI | 元宇宙 | 安森美 | ADI |
无刷电机 | FOC | IGBT | 逆变器 | 文心一言 | 5G | 英飞凌 | 罗姆 |
直流电机 | PID | MOSFET | 传感器 | 人工智能 | 物联网 | NXP | 赛灵思 |
步进电机 | SPWM | 充电桩 | IPM | 机器视觉 | 无人机 | 三菱电机 | ST |
伺服电机 | SVPWM | 光伏发电 | UPS | AR | 智能电网 | 国民技术 | Microchip |
开关电源 | 步进电机 | 无线充电 | LabVIEW | EMC | PLC | OLED | 单片机 |
5G | m2m | DSP | MCU | ASIC | CPU | ROM | DRAM |
NB-IoT | LoRa | Zigbee | NFC | 蓝牙 | RFID | Wi-Fi | SIGFOX |
Type-C | USB | 以太网 | 仿真器 | RISC | RAM | 寄存器 | GPU |
语音识别 | 万用表 | CPLD | 耦合 | 电路仿真 | 电容滤波 | 保护电路 | 看门狗 |
CAN | CSI | DSI | DVI | Ethernet | HDMI | I2C | RS-485 |
SDI | nas | DMA | HomeKit | 阈值电压 | UART | 机器学习 | TensorFlow |
Arduino | BeagleBone | 树莓派 | STM32 | MSP430 | EFM32 | ARM mbed | EDA |
示波器 | LPC | imx8 | PSoC | Altium Designer | Allegro | Mentor | Pads |
OrCAD | Cadence | AutoCAD | 华秋DFM | Keil | MATLAB | MPLAB | Quartus |
C++ | Java | Python | JavaScript | node.js | RISC-V | verilog | Tensorflow |
Android | iOS | linux | RTOS | FreeRTOS | LiteOS | RT-THread | uCOS |
DuerOS | Brillo | Windows11 | HarmonyOS |