比较难做到。
鹿鼎记(电子版)俺一晚上就能看完,大唐双龙传(电子版)两天能看完,
但是 The Da Vinci Code 那么薄的一本书俺也要一天才看完。
俺家小孩看英文书也不算很快, 一般也是一个晚上看一本。
在朋友圈里俺也算是 “英语好”的人,甚至俺老婆的导师也这么评价俺。俺就当仁不让冒充一把英语好的人, 蹭些盐值,大家请海涵。
附录:
C 环形缓冲的实现: 音频采集后续小实验后续小实验RING/CIRCULAR BUFFER 附送源码
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
俺对 C 一窍不通,看到知乎用户里面程序员人均收入 50 万, 俺也想着培养自己的孩子学编程。但如果父母一点都不懂, 恐怕也难以激发孩子学编程的热情。
俺初中毕业, 没啥文化, 大伙都知道。俺从最开始的 GTK HELLO WORLD 开始, 连滚带爬地,事先开始了自己的征途。这些散文, 就是最近的足迹。
C 音频捕捉的小实验的后续小实验的后续小实验。。。。。。把缓冲区的数据倒到硬盘文件(已完成)。原先存在的问题:BUFFER 的 RAW DATA 通过 BOUBLE BUFFER 再写到硬盘上, 重放没有问题。 RAW DATA 通过端序转换, 存入数组(SIGNED INT 或者 FLOAT), 存入硬盘文件以后。 通过软件重放, 发现存在高频噪音。(已解决)
缓冲区数据转换成 INT 或 FLOAT 或 DOUBLE,端序的问题貌似已经理解。
言归正传
圆形缓冲区(circular buffer),循环缓冲区(cyclic buffer),环形缓冲区(ring buffer),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存实时数据流。
环形缓存放置在20041到20048这8个连续的存储位置。图A示来自输入的8个样本在某一特定瞬间可能被存储的情况,而图B示下一个样本被采集后的变化。
圆形缓冲区需要4个指针: 在内存中实际开始位置; 在内存中实际结束位置,也可以用缓冲区长度代替; 存储在缓冲区中的有效数据的开始位置(读指针 或数据队列头部指针【计数*标志】); 存储在缓冲区中的有效数据的结尾位置(写指针 或数据队列尾部指针【计数*标志】)。
环形缓存的技术是这样的,通过重新映射,这个线性数组的终点与它的起点相连。存储位置20041被重新映射成20048的紧邻,就象20044在20045的旁边。通过一个指针来跟踪这个数组,这个指针表示最新的样本落脚的位置。
例如:在图a中,指针包含地址20044,而在图b中,它重定向指向20045。当采集一个新样本时,它总是取代数组中最老的样本,而指针则向前移一个地址。环形缓存的效率很高,因为在获取新样本时只需要改变一个值。管理一个循环缓冲区需要四个参数。
首先,必须有个指针,指示内存中循环缓冲区的起始位置(例如20041)。
第二,必须有一个指示数组结束的指针(例如20048),或者一个存储其数组长度的变量(例如“8”)。
第三,必须指定内存寻址的步长。 例如: 地址20043包含一个样本,地址20044包含下一个样本,以此类推。 但是现实情况可能有变化。例如寻址可能
指的是字节,每个样本可能需要两个或四个字节。在这些情况下,步长大小需要2或4。以上三个值定义了循环缓冲区的大小和配置,在程序运行过程中不会改变。
第四个值,也就是指向最近样本的指针,必须在每次获取新样本时进行修改。
换句话说,必须有逻辑来控制这第四个值根据前三个值的值进行更新。
备注: 卷积不需要循环缓冲,因为每个样本都可以立即被访问。然而,许多算法是分阶段实现的,每个阶段之间都会产生一个中间过渡信号。就象一个递归滤波器作一系列的二象限滤波就以这种方式。当然暴荔法是将每个中间过渡信号的全部存在内存里。环形缓存提供了一种选择:只存储手头计算所需的那些中间样本,可以减少所需的内存,代价是要烧脑重新映射。重要的是,环形缓存对实时应用至关重要,而对离线处理不过是有用罢了。
https://embedjournal.com/implementing-circular-buffer-embedded-c/ https://towardsdatascience.com/circular-queue-or-ring-buffer-92c7b0193326 https://troydhanson.github.io/uthash/utringbuffer.html https://elexfocus.com/implement-a-circular-buffer-in-c/ http://www.equestionanswers.com/c/c-circular-buffer.php https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/ https://www.avrfreaks.net/forum/ring-buffer-0?page=all https://www.codeproject.com/Tips/5258667/A-Generic-Circular-Buffer-in-Csharp http://blog.acipo.com/generating-wave-files-in-c/
网上有无数的样板, 但是能用的不多。
例子:
struct cbuff { size_t *rtdata; size_t trunk; size_t *head_ptr; size_t *tail_ptr; bool isfullcb; }; void init_rqb(struct cbuff *mcb, size_t *mdata, size_t size_power_of_two); int put_rqb(struct cbuff *mcb, size_t mdata); int get_rqb(struct cbuff *mcb); int capof_cqb(struct cbuff *mcb); int cell_cqb(struct cbuff *mcb); void init_rqb(struct cbuff *mcb, size_t *rt_stream_ptr, size_t rt_size) { mcb->rtdata = rt_stream_ptr; mcb->trunk = rt_size - 1; mcb->head_ptr = 0; mcb->tail_ptr = 0; } int put_rqb(struct cbuff *mcb, size_t mdata) { if(((mcb->head_ptr - mcb->tail_ptr) & mcb->trunk) == mcb->trunk) { return 0; } DO_SOMETHING(size_t, mcb->rtdata[mcb->head_ptr]) = mdata; DO_SOMETHING(size_t, mcb->head_ptr) = (mcb->head_ptr + 1) & mcb->trunk; return 1; } int get_rqb(struct cbuff *mcb) { size_t mdata; if(((mcb->head_ptr - mcb->tail_ptr) & mcb->trunk) > 0) { mdata = DO_SOMETHING(size_t, mcb->rtdata[mcb->tail_ptr]); DO_SOMETHING(size_t, mcb->tail_ptr) = (mcb->tail_ptr + 1) & mcb->trunk; return mdata; } else { return -1; } } int capof_cqb(struct cbuff *mcb) { return mcb->trunk + 1; } int cell_cqb(struct cbuff *mcb) { return (mcb->head_ptr - mcb->tail_ptr) & mcb->trunk;}
俺强行消化了一下, 花了 72 小时。
对于中老年人来说确实是有点费解。
CB_WENXUE.c
// CB_WENXUE.c // // A SIMPLE CIRCULAR BUFFER EXAMPLE // // LICENSE : WTFPL // #include <stdio.h> #include <pthread.h> #include <unistd.h> //sleep() is from here #include <malloc.h> #include <sched.h> #include <string.h> #include <stdbool.h> #include <stdint.h> #define DATACAP 16 typedef struct cbuff{ float rt_arr[DATACAP]; int dhead_p; //实际上是 GLOBAL 全局计数器 int dtail_p; int dqlen; }*RQB; struct cbuff *init_cb(void){ struct cbuff *cbStru_ptr = NULL; cbStru_ptr = (struct cbuff *)malloc(sizeof(struct cbuff)); if(cbStru_ptr == NULL) { puts("init_cb: Mem alloc error!
"); return NULL;} cbStru_ptr->dhead_p = 0; cbStru_ptr->dtail_p = 0; cbStru_ptr->dqlen = 0; return cbStru_ptr; } // KEEP IT SIMPLE int isfull_cb(struct cbuff *cbStru_ptr){ return (cbStru_ptr->dqlen == DATACAP) & (cbStru_ptr->dhead_p == cbStru_ptr->dtail_p ); } int isempt_cb(struct cbuff *cbStru_ptr){ return (cbStru_ptr->dqlen != DATACAP) & (cbStru_ptr->dhead_p == cbStru_ptr->dtail_p) ; } int isXrun_cb(struct cbuff *cbStru_ptr){ return (cbStru_ptr->dqlen !=0) & (cbStru_ptr->dhead_p == cbStru_ptr->dtail_p ); } // Delete one element from Data Queue int poll_cb(struct cbuff *cbStru_ptr) { if( isempt_cb(cbStru_ptr) ) { puts("poll_cb: buffer queue is empty"); return -1;} else { cbStru_ptr->rt_arr[ (cbStru_ptr->dhead_p + 1) % DATACAP ] ; cbStru_ptr->dqlen = cbStru_ptr->dqlen -1 ; } return 0 ; } int put_cb(struct cbuff *cbStru_ptr, float rt_data) { if( isfull_cb(cbStru_ptr) ) { puts("put_cb: buffer queue is full. Overwriting data.
"); cbStru_ptr->rt_arr[ cbStru_ptr->dtail_p % DATACAP ] = rt_data; printf (" put_cb:data %f , stored to pos--> %d
", rt_data, (cbStru_ptr->dtail_p) ); cbStru_ptr->dtail_p = (cbStru_ptr->dhead_p +1) % DATACAP ; cbStru_ptr->dhead_p = (cbStru_ptr->dhead_p +1) % DATACAP ; cbStru_ptr->dqlen = DATACAP ; printf ("put_cb:data queue Head ----------------->>> %d
", cbStru_ptr->dhead_p ); printf ("put_cb:data queue Tail ------------------->>> %d
", cbStru_ptr->dtail_p ); printf ("put_cb:data queue Length-------->>> %d
", cbStru_ptr->dqlen ); return -10089; } else { cbStru_ptr->rt_arr[ (cbStru_ptr->dtail_p) % DATACAP ] = rt_data; printf ("put_cb:data %f , stored to pos--> %d
", rt_data, (cbStru_ptr->dtail_p) ); cbStru_ptr->dtail_p = (cbStru_ptr->dtail_p +1) % DATACAP ; //cbStru_ptr->dqlen = cbStru_ptr->dqlen +1 ; cbStru_ptr->dqlen = cbStru_ptr->dqlen +1 ; printf ("put_cb:data queue Head -------------------> %d
", cbStru_ptr->dhead_p ); printf ("put_cb:data queue Tail ---------------------> %d
", cbStru_ptr->dtail_p ); printf ("put_cb:data queue Length----------> %d
", cbStru_ptr->dqlen ); return 0 ; } } float get_cb(struct cbuff *cbStru_ptr, float rt_data ) { if(isempt_cb(cbStru_ptr) ) { puts("
get_cb:buffer empty :p
"); return -10086; } else { rt_data = cbStru_ptr->rt_arr[ cbStru_ptr->dhead_p % DATACAP ]; cbStru_ptr->dhead_p = (cbStru_ptr->dhead_p +1) % DATACAP ; cbStru_ptr->dqlen = (cbStru_ptr->dqlen -1) % DATACAP; return rt_data; } } // Clear the Data Queue int reset_cb(struct cbuff *cbStru_ptr) { cbStru_ptr->dhead_p = 0; cbStru_ptr->dtail_p = 0; cbStru_ptr->dqlen =0; printf( "
reset_cb: Address of Array:%p, Array pointer Size:%d
", cbStru_ptr, sizeof(cbStru_ptr->rt_arr)); return 0; } int gc_cb(struct cbuff *cbStru_ptr) { if(cbStru_ptr == NULL) { puts("gc_cb: pointer null
"); return -1; } free(cbStru_ptr); return 0; } /////////////////////////////////////////////////////////////////////////////////// int main() { float test_input = 0.111111, ret_float; int ret_err; RQB my_cbuff_ptr; my_cbuff_ptr = init_cb(); reset_cb(my_cbuff_ptr) ; printf ("
Size of CBStruct:%d
", sizeof(struct cbuff)); //testing for(int i = 0;i< 50;i++) { ret_err = put_cb(my_cbuff_ptr, i * test_input) ; if(ret_err==0 ) { printf("
Attempt %d: %10.5f <<<<<<<<<<ERROR: %d <<<<<<<<<<<<<<<<<<< Data to inject
", (i+1), i * test_input , ret_err); printf("Data queue Length: %d:
", my_cbuff_ptr->dqlen ); printf("Data injected: %f:
", my_cbuff_ptr->dhead_p ); } else { printf("
Attempt %d: %10.5f <<<<<<<<<<ERROR: %d <<<<<<<<<<<<<<<<<<< Data to inject
", (i+1), i * test_input, ret_err); printf("Data queue Length: %d:
", my_cbuff_ptr->dqlen ); printf("Data injected: %f:
", my_cbuff_ptr->dhead_p ); printf (" Error: %d
", ret_err); } } sleep(1); for(int i = 0;i<32;i++) { ret_float = get_cb(my_cbuff_ptr, ret_float); printf("
get attempt %d ---> %10.5f
", (1+i), ret_float); } //testing 2 for(int i = 0;i< 16;i++) { ret_err = put_cb(my_cbuff_ptr, i * test_input) ; if(ret_err==0 ) { printf("
Test2 try %d: %10.5f <<<<<<<<<<ERROR: %d <<<<<<<<<<<<<<<<<<< Data to inject
", (i+1), i * test_input , ret_err); printf("Data queue Length: %d:
", my_cbuff_ptr->dqlen ); printf("Data injected: %f:
", my_cbuff_ptr->dhead_p ); } else { printf("
Test2 try %d: %10.5f <<<<<<<<<<ERROR: %d <<<<<<<<<<<<<<<<<<< Data to inject
", (i+1), i * test_input, ret_err); printf("Data queue Length: %d:
", my_cbuff_ptr->dqlen ); printf("Data injected: %f:
", my_cbuff_ptr->dhead_p ); printf (" Error: %d
", ret_err); } } sleep(1); for(int i = 0;i<16;i++) { ret_float = get_cb(my_cbuff_ptr, ret_float); printf("
get attempt %d ---> %10.5f
", (1+i), ret_float); } gc_cb(my_cbuff_ptr); return 0; }
输出效果:
reset_cb: Address of Array:0x40eb90, Array pointer Size:64 Size of CBStruct:76 put_cb:data 0.000000 , stored to pos--> 0 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 1 put_cb:data queue Length----------> 1 Attempt 1: 0.00000 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 1: Data injected: 0.000000: put_cb:data 0.111111 , stored to pos--> 1 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 2 put_cb:data queue Length----------> 2 Attempt 2: 0.11111 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 2: Data injected: 0.111111: put_cb:data 0.222222 , stored to pos--> 2 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 3 put_cb:data queue Length----------> 3 Attempt 3: 0.22222 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 3: Data injected: 0.222222: put_cb:data 0.333333 , stored to pos--> 3 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 4 put_cb:data queue Length----------> 4 Attempt 4: 0.33333 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 4: Data injected: 0.333333: put_cb:data 0.444444 , stored to pos--> 4 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 5 put_cb:data queue Length----------> 5 Attempt 5: 0.44444 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 5: Data injected: 0.444444: put_cb:data 0.555555 , stored to pos--> 5 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 6 put_cb:data queue Length----------> 6 Attempt 6: 0.55555 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 6: Data injected: 0.555555: put_cb:data 0.666666 , stored to pos--> 6 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 7 put_cb:data queue Length----------> 7 Attempt 7: 0.66667 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 7: Data injected: 0.666666: put_cb:data 0.777777 , stored to pos--> 7 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 8 put_cb:data queue Length----------> 8 Attempt 8: 0.77778 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 8: Data injected: 0.777777: put_cb:data 0.888888 , stored to pos--> 8 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 9 put_cb:data queue Length----------> 9 Attempt 9: 0.88889 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 9: Data injected: 0.888888: put_cb:data 0.999999 , stored to pos--> 9 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 10 put_cb:data queue Length----------> 10 Attempt 10: 1.00000 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 10: Data injected: 0.999999: put_cb:data 1.111110 , stored to pos--> 10 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 11 put_cb:data queue Length----------> 11 Attempt 11: 1.11111 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 11: Data injected: 1.111110: put_cb:data 1.222221 , stored to pos--> 11 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 12 put_cb:data queue Length----------> 12 Attempt 12: 1.22222 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 12: Data injected: 1.222221: put_cb:data 1.333332 , stored to pos--> 12 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 13 put_cb:data queue Length----------> 13 Attempt 13: 1.33333 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 13: Data injected: 1.333332: put_cb:data 1.444443 , stored to pos--> 13 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 14 put_cb:data queue Length----------> 14 Attempt 14: 1.44444 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 14: Data injected: 1.444443: put_cb:data 1.555554 , stored to pos--> 14 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 15 put_cb:data queue Length----------> 15 Attempt 15: 1.55555 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 15: Data injected: 1.555554: put_cb:data 1.666665 , stored to pos--> 15 put_cb:data queue Head -------------------> 0 put_cb:data queue Tail ---------------------> 0 put_cb:data queue Length----------> 16 Attempt 16: 1.66666 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 1.666665: put_cb: buffer queue is full. Overwriting data. put_cb:data 1.777776 , stored to pos--> 0 put_cb:data queue Head ----------------->>> 1 put_cb:data queue Tail ------------------->>> 1 put_cb:data queue Length-------->>> 16 Attempt 17: 1.77778 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 1.777776: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 1.888887 , stored to pos--> 1 put_cb:data queue Head ----------------->>> 2 put_cb:data queue Tail ------------------->>> 2 put_cb:data queue Length-------->>> 16 Attempt 18: 1.88889 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 1.888887: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 1.999998 , stored to pos--> 2 put_cb:data queue Head ----------------->>> 3 put_cb:data queue Tail ------------------->>> 3 put_cb:data queue Length-------->>> 16 Attempt 19: 2.00000 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 1.999998: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.111109 , stored to pos--> 3 put_cb:data queue Head ----------------->>> 4 put_cb:data queue Tail ------------------->>> 4 put_cb:data queue Length-------->>> 16 Attempt 20: 2.11111 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.111109: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.222220 , stored to pos--> 4 put_cb:data queue Head ----------------->>> 5 put_cb:data queue Tail ------------------->>> 5 put_cb:data queue Length-------->>> 16 Attempt 21: 2.22222 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.222220: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.333331 , stored to pos--> 5 put_cb:data queue Head ----------------->>> 6 put_cb:data queue Tail ------------------->>> 6 put_cb:data queue Length-------->>> 16 Attempt 22: 2.33333 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.333331: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.444442 , stored to pos--> 6 put_cb:data queue Head ----------------->>> 7 put_cb:data queue Tail ------------------->>> 7 put_cb:data queue Length-------->>> 16 Attempt 23: 2.44444 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.444442: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.555553 , stored to pos--> 7 put_cb:data queue Head ----------------->>> 8 put_cb:data queue Tail ------------------->>> 8 put_cb:data queue Length-------->>> 16 Attempt 24: 2.55555 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.555553: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.666664 , stored to pos--> 8 put_cb:data queue Head ----------------->>> 9 put_cb:data queue Tail ------------------->>> 9 put_cb:data queue Length-------->>> 16 Attempt 25: 2.66666 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.666664: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.777775 , stored to pos--> 9 put_cb:data queue Head ----------------->>> 10 put_cb:data queue Tail ------------------->>> 10 put_cb:data queue Length-------->>> 16 Attempt 26: 2.77778 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.777775: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.888886 , stored to pos--> 10 put_cb:data queue Head ----------------->>> 11 put_cb:data queue Tail ------------------->>> 11 put_cb:data queue Length-------->>> 16 Attempt 27: 2.88889 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.888886: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 2.999997 , stored to pos--> 11 put_cb:data queue Head ----------------->>> 12 put_cb:data queue Tail ------------------->>> 12 put_cb:data queue Length-------->>> 16 Attempt 28: 3.00000 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 2.999997: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.111108 , stored to pos--> 12 put_cb:data queue Head ----------------->>> 13 put_cb:data queue Tail ------------------->>> 13 put_cb:data queue Length-------->>> 16 Attempt 29: 3.11111 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.111108: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.222219 , stored to pos--> 13 put_cb:data queue Head ----------------->>> 14 put_cb:data queue Tail ------------------->>> 14 put_cb:data queue Length-------->>> 16 Attempt 30: 3.22222 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.222219: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.333330 , stored to pos--> 14 put_cb:data queue Head ----------------->>> 15 put_cb:data queue Tail ------------------->>> 15 put_cb:data queue Length-------->>> 16 Attempt 31: 3.33333 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.333330: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.444441 , stored to pos--> 15 put_cb:data queue Head ----------------->>> 0 put_cb:data queue Tail ------------------->>> 0 put_cb:data queue Length-------->>> 16 Attempt 32: 3.44444 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.444441: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.555552 , stored to pos--> 0 put_cb:data queue Head ----------------->>> 1 put_cb:data queue Tail ------------------->>> 1 put_cb:data queue Length-------->>> 16 Attempt 33: 3.55555 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.555552: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.666663 , stored to pos--> 1 put_cb:data queue Head ----------------->>> 2 put_cb:data queue Tail ------------------->>> 2 put_cb:data queue Length-------->>> 16 Attempt 34: 3.66666 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.666663: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.777774 , stored to pos--> 2 put_cb:data queue Head ----------------->>> 3 put_cb:data queue Tail ------------------->>> 3 put_cb:data queue Length-------->>> 16 Attempt 35: 3.77777 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.777774: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.888885 , stored to pos--> 3 put_cb:data queue Head ----------------->>> 4 put_cb:data queue Tail ------------------->>> 4 put_cb:data queue Length-------->>> 16 Attempt 36: 3.88889 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.888885: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 3.999996 , stored to pos--> 4 put_cb:data queue Head ----------------->>> 5 put_cb:data queue Tail ------------------->>> 5 put_cb:data queue Length-------->>> 16 Attempt 37: 4.00000 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 3.999996: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.111107 , stored to pos--> 5 put_cb:data queue Head ----------------->>> 6 put_cb:data queue Tail ------------------->>> 6 put_cb:data queue Length-------->>> 16 Attempt 38: 4.11111 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.111107: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.222218 , stored to pos--> 6 put_cb:data queue Head ----------------->>> 7 put_cb:data queue Tail ------------------->>> 7 put_cb:data queue Length-------->>> 16 Attempt 39: 4.22222 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.222218: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.333329 , stored to pos--> 7 put_cb:data queue Head ----------------->>> 8 put_cb:data queue Tail ------------------->>> 8 put_cb:data queue Length-------->>> 16 Attempt 40: 4.33333 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.333329: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.444440 , stored to pos--> 8 put_cb:data queue Head ----------------->>> 9 put_cb:data queue Tail ------------------->>> 9 put_cb:data queue Length-------->>> 16 Attempt 41: 4.44444 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.444440: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.555551 , stored to pos--> 9 put_cb:data queue Head ----------------->>> 10 put_cb:data queue Tail ------------------->>> 10 put_cb:data queue Length-------->>> 16 Attempt 42: 4.55555 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.555551: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.666662 , stored to pos--> 10 put_cb:data queue Head ----------------->>> 11 put_cb:data queue Tail ------------------->>> 11 put_cb:data queue Length-------->>> 16 Attempt 43: 4.66666 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.666662: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.777773 , stored to pos--> 11 put_cb:data queue Head ----------------->>> 12 put_cb:data queue Tail ------------------->>> 12 put_cb:data queue Length-------->>> 16 Attempt 44: 4.77777 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.777773: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.888884 , stored to pos--> 12 put_cb:data queue Head ----------------->>> 13 put_cb:data queue Tail ------------------->>> 13 put_cb:data queue Length-------->>> 16 Attempt 45: 4.88888 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.888884: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 4.999995 , stored to pos--> 13 put_cb:data queue Head ----------------->>> 14 put_cb:data queue Tail ------------------->>> 14 put_cb:data queue Length-------->>> 16 Attempt 46: 5.00000 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 4.999995: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 5.111106 , stored to pos--> 14 put_cb:data queue Head ----------------->>> 15 put_cb:data queue Tail ------------------->>> 15 put_cb:data queue Length-------->>> 16 Attempt 47: 5.11111 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 5.111106: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 5.222217 , stored to pos--> 15 put_cb:data queue Head ----------------->>> 0 put_cb:data queue Tail ------------------->>> 0 put_cb:data queue Length-------->>> 16 Attempt 48: 5.22222 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 5.222217: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 5.333328 , stored to pos--> 0 put_cb:data queue Head ----------------->>> 1 put_cb:data queue Tail ------------------->>> 1 put_cb:data queue Length-------->>> 16 Attempt 49: 5.33333 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 5.333328: Error: -10089 put_cb: buffer queue is full. Overwriting data. put_cb:data 5.444439 , stored to pos--> 1 put_cb:data queue Head ----------------->>> 2 put_cb:data queue Tail ------------------->>> 2 put_cb:data queue Length-------->>> 16 Attempt 50: 5.44444 <<<<<<<<<<ERROR: -10089 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 5.444439: Error: -10089 get attempt 1 ---> 3.77777 get attempt 2 ---> 3.88889 get attempt 3 ---> 4.00000 get attempt 4 ---> 4.11111 get attempt 5 ---> 4.22222 get attempt 6 ---> 4.33333 get attempt 7 ---> 4.44444 get attempt 8 ---> 4.55555 get attempt 9 ---> 4.66666 get attempt 10 ---> 4.77777 get attempt 11 ---> 4.88888 get attempt 12 ---> 5.00000 get attempt 13 ---> 5.11111 get attempt 14 ---> 5.22222 get attempt 15 ---> 5.33333 get attempt 16 ---> 5.44444 get_cb:buffer empty :p get attempt 17 ---> -10086.00000 get_cb:buffer empty :p get attempt 18 ---> -10086.00000 get_cb:buffer empty :p get attempt 19 ---> -10086.00000 get_cb:buffer empty :p get attempt 20 ---> -10086.00000 get_cb:buffer empty :p get attempt 21 ---> -10086.00000 get_cb:buffer empty :p get attempt 22 ---> -10086.00000 get_cb:buffer empty :p get attempt 23 ---> -10086.00000 get_cb:buffer empty :p get attempt 24 ---> -10086.00000 get_cb:buffer empty :p get attempt 25 ---> -10086.00000 get_cb:buffer empty :p get attempt 26 ---> -10086.00000 get_cb:buffer empty :p get attempt 27 ---> -10086.00000 get_cb:buffer empty :p get attempt 28 ---> -10086.00000 get_cb:buffer empty :p get attempt 29 ---> -10086.00000 get_cb:buffer empty :p get attempt 30 ---> -10086.00000 get_cb:buffer empty :p get attempt 31 ---> -10086.00000 get_cb:buffer empty :p get attempt 32 ---> -10086.00000 put_cb:data 0.000000 , stored to pos--> 2 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 3 put_cb:data queue Length----------> 1 Test2 try 1: 0.00000 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 1: Data injected: 0.000000: put_cb:data 0.111111 , stored to pos--> 3 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 4 put_cb:data queue Length----------> 2 Test2 try 2: 0.11111 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 2: Data injected: 0.111111: put_cb:data 0.222222 , stored to pos--> 4 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 5 put_cb:data queue Length----------> 3 Test2 try 3: 0.22222 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 3: Data injected: 0.222222: put_cb:data 0.333333 , stored to pos--> 5 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 6 put_cb:data queue Length----------> 4 Test2 try 4: 0.33333 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 4: Data injected: 0.333333: put_cb:data 0.444444 , stored to pos--> 6 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 7 put_cb:data queue Length----------> 5 Test2 try 5: 0.44444 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 5: Data injected: 0.444444: put_cb:data 0.555555 , stored to pos--> 7 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 8 put_cb:data queue Length----------> 6 Test2 try 6: 0.55555 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 6: Data injected: 0.555555: put_cb:data 0.666666 , stored to pos--> 8 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 9 put_cb:data queue Length----------> 7 Test2 try 7: 0.66667 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 7: Data injected: 0.666666: put_cb:data 0.777777 , stored to pos--> 9 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 10 put_cb:data queue Length----------> 8 Test2 try 8: 0.77778 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 8: Data injected: 0.777777: put_cb:data 0.888888 , stored to pos--> 10 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 11 put_cb:data queue Length----------> 9 Test2 try 9: 0.88889 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 9: Data injected: 0.888888: put_cb:data 0.999999 , stored to pos--> 11 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 12 put_cb:data queue Length----------> 10 Test2 try 10: 1.00000 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 10: Data injected: 0.999999: put_cb:data 1.111110 , stored to pos--> 12 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 13 put_cb:data queue Length----------> 11 Test2 try 11: 1.11111 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 11: Data injected: 1.111110: put_cb:data 1.222221 , stored to pos--> 13 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 14 put_cb:data queue Length----------> 12 Test2 try 12: 1.22222 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 12: Data injected: 1.222221: put_cb:data 1.333332 , stored to pos--> 14 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 15 put_cb:data queue Length----------> 13 Test2 try 13: 1.33333 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 13: Data injected: 1.333332: put_cb:data 1.444443 , stored to pos--> 15 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 0 put_cb:data queue Length----------> 14 Test2 try 14: 1.44444 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 14: Data injected: 1.444443: put_cb:data 1.555554 , stored to pos--> 0 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 1 put_cb:data queue Length----------> 15 Test2 try 15: 1.55555 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 15: Data injected: 1.555554: put_cb:data 1.666665 , stored to pos--> 1 put_cb:data queue Head -------------------> 2 put_cb:data queue Tail ---------------------> 2 put_cb:data queue Length----------> 16 Test2 try 16: 1.66666 <<<<<<<<<<ERROR: 0 <<<<<<<<<<<<<<<<<<< Data to inject Data queue Length: 16: Data injected: 1.666665: get attempt 1 ---> 0.00000 get attempt 2 ---> 0.11111 get attempt 3 ---> 0.22222 get attempt 4 ---> 0.33333 get attempt 5 ---> 0.44444 get attempt 6 ---> 0.55555 get attempt 7 ---> 0.66667 get attempt 8 ---> 0.77778 get attempt 9 ---> 0.88889 get attempt 10 ---> 1.00000 get attempt 11 ---> 1.11111 get attempt 12 ---> 1.22222 get attempt 13 ---> 1.33333 get attempt 14 ---> 1.44444 get attempt 15 ---> 1.55555 get attempt 16 ---> 1.66666 [wenxue@hpi7 alsaaa]$
防止有人不看完就血脉贲张,我先把自己的观点凝练总结一下:
尺度适当且全场保持一致,就是好判罚;如果尺度不一致,或者本来尺度一致,最后这下突然不一致,就不是好判罚。所以只有看完了全场比赛才有资格讨论,而不是拿几张截图抠足球规则说事。
皇马1:3尤文的比赛已经过去好多天了,我还是要炒个冷饭。
因为自己是一方球迷,很难在赛后冷静看待,所以赛后不说正事只说情绪。情绪平复了再说正事。
那个点球到底该不该判?
或者说,这是不是个好的判罚?
又或者说,好的判罚的标准是什么?
有人说,标准当然是按照足球规则,该判就判,不该判就不判。
我说——放屁!
只有完全没看过足球比赛的才会说出这种屁话。
真严格按照足球规则来执法比赛,足球比赛就没法看了。
足球规则和判罚真的构成了那一句老生常谈——“严格立法、普遍违法、选择性执法”。
常看足球比赛的都知道,场上球员身体接触根本避免不了——撞人、踢人、推人、拉人,几乎每分钟都在发生。说到底足球是个富有激情的男性运动,男性荷尔蒙里自带侵略属性,你把这些东西完全杜绝了,球员在场上缩手缩脚,不敢做动作,足球运动早被观众唾弃了。
如果裁判完全按照足球规则来吹比赛,一犯规就吹,比赛每分钟都要暂停一下,这叫好的判罚?
好的判罚怎么体现?
两个字——平衡。
坏的判罚怎么体现?
两个字——平衡。
那位说了,好坏都是平衡,你说的才是屁话。姑且说这就是屁话,往下听——
好的平衡是裁判选择一个折衷的判罚尺度。
如果判罚尺度过松,对场上球员的约束小,场面太脏,会变成踢野球,足球运动的技战术之美无法发挥,完全成了身体对抗;如果判罚尺度过紧,就不免要经常吹哨,把球变成死球,严重影响比赛的流畅性,裁判反倒成了主角。
好的判罚就是要在尺度上找一个平衡,裁判在有作为的情况下不抢戏,保证比赛既流畅又不至于动作太脏。
坏的平衡是裁判在两队之间找平衡。
往往这样的裁判心虚,不够自信,又总想显得自己很公平。判罚时不能冷静,判了A队之后又后悔,为了补偿就只好找B队的毛病,判了之后再次后悔,又反过来放松B队严吹A队,导致整场比赛尺度游移不定,但双方在吃牌和危险区域定位球(包括点球)数量上达到了某种平衡。
这种平衡就是坏的平衡。
相比之下,坏的平衡容易操作,好的平衡不容易掌握,所以好裁判难得。
那么什么样的尺度是可以达到好的平衡呢?
答案是:看情况。
好的尺度不是唯一的,而是看双方在这场比赛的具体表现。
如果双方都踢得很文明,尺度就不妨严一点,双方都不会有意见,大家都玩技术不玩身体,那就拼技术呗。
如果双方都踢得很脏,尺度就不妨稍松一点,为了比赛的流畅性,规则什么的就灵活掌握了,守住底线,小动作什么的就算了。
如果一方比较脏一方比较文明,那就要想办法让脏的一方收敛收敛,除了通过判罚之外,裁判与球员的沟通也很重要,让球员明白,我并不是针对你,但我不能放任你这么玩,你们也不想吃牌下去几个吧?
所以正确的操作应该是在开场前30分钟,裁判先要适应双方的风格,然后修正判罚尺度,这30分钟内如果尺度不一致大家也都能理解,毕竟比赛刚开始,双方都有机会,这段时间是球员和裁判博弈的时间,裁判在试探,球员也在试探。慢慢的,双方最终达成一致——这场比赛到底应该是什么尺度。裁判和球员磨合之后产生无声的默契——球员大概知道自己做什么样的动作裁判不会管,什么样的动作裁判会干预;裁判也大概知道球员对什么样的判罚会抗议,对什么样的会默许。尺度一旦达成,就要一直按这个尺度来,双方会一直不断地向裁判施压,为自己一方争利,裁判要做的就是顶住压力,维持尺度。
这才是真正的足球规则!真正的球场跟写在Laws of the Game上的乌托邦是两个世界!
如果裁判尺度不一致,比如全场吹罚都比较松,最后突然紧一下,本来之前都不吹的动作,这时给个点球或红牌,甚至红点套餐,球员不围过来才怪!
因为球员的心理活动是——"I trusted you!" (我白相信你了!)会有一种被欺骗的感觉。比赛都进行了一大半了你突然变个尺度,你玩我呢?
回到皇马1:3尤文那场比赛最后的点球,贝纳蒂亚动作并不大,如果是一个扫堂腿直接撂倒了巴斯克斯,我相信就算是尤文球迷(或者巴萨球迷,嘿嘿),就算这是93分钟,就算尤文几乎创造了奇迹,就算这是布冯最后一次欧冠,谁也说不出什么来,都只会骂贝纳蒂亚,不会骂裁判。但现在这么个动作——说他推人了,似乎也可以说是惯性动作;说他抬脚过高,禁区内解围谁管那么多;说他碰到球了,似乎又是在身体接触后碰到的,到底该不该判?
按照上面说过的标准,我们要看的就是,这个判罚,是否与整场比赛的尺度一致。那么就只有看过全场比赛的人才有评判的先决条件。拿出那几分钟的截图,再把足球规则搬出来,那都是球盲。
没看整场比赛的人首先都闭嘴。
我没看整场比赛,所以我闭嘴。
看过整场比赛的,相信你们心里已经有了答案(虽然是不一样的答案,现在你们有资格继续掐了)。