byte[] buffer = new byte[2*1200];
targetDataLine.read(buffer, 0, buffer.length)
for ( int i = 0; i < n; i+=2 ) {
int value = (short)((buffer[i]&0xFF) | ((buffer[i+1]&0xFF) << 8)); //**Don't understand**
a[i >> 1] = value;
}
到目前为止,我掌握的是这样的:
>
从另一篇SO文章中,我了解到存储在较大类型中的每个字节都必须是&
,并带有0xFF,因为它被转换为32位数字。我猜前导的24位是用1
s填充的(尽管我不知道为什么它不是用零填充的......用1
s前导难道不会改变数字的值吗?0000000010
(2)毕竟与111111110010
(-14)不同。)所以0xff
的目的是只抓取最后的8位(即整个字节)。
当缓冲区[i+1]
左移8位时,这使得当或
ing时,缓冲区[i+1]
中的8位位于最高有效位置,而缓冲区[i]
中的8位位于最低有效位置。我们最后得到一个形式为buffer[i+1]+buffer[i]
的16位数字。(我使用的是+
,但我知道它更接近串联。)
首先,为什么我们或
ingbuffer[i]buffer[i+1]<<8
?这似乎破坏了原来的声音信息,除非我们用同样的方法把它拉回来;虽然我知道或
将把它们组合成一个值,但我不知道该值在以后的计算中如何有用或使用。以后访问此数据的唯一方法是将其作为文字值:
diff += Math.abs(a[j]-a[i+j];
如果我有101
和111
,加在一起应该得到12,或者1100
。但是101111<<<3
给出111101
,等于61。我最接近的理解是101
(5)111000
(56)与添加5+56=61
相同。但是顺序很重要--执行相反的101<<3111
是完全不同的。我真的不明白这些数据如何能保持有用,当它是或已经是这样的。
我遇到的另一个问题是,因为Java使用有符号的字节,第八个位置不表示值,而是符号。如果或
使用两个二进制有符号数字,那么在得到的16位数字中,位于2的位现在充当值而不是占位符。如果在运行或
之前有一个负字节,那么在最后的值后操作中,它现在将错误地表现为原始数字中有一个正2。0xff
并没有消除这一点,因为它保留了第八个带符号的字节,所以这不应该是一个问题吗?
例如,1111
(-1)和0101
,when或Gd,可能给出01011111
。但是1111
并不表示正的1111
,而是表示签名版本;然而,在最终的答案中,它现在是一个积极的2点。
更新:我标记了接受的答案,但它需要+一点额外的工作来找出我哪里出错了。对于任何将来可能读到这篇文章的人来说:
>
就签名而言,我的代码使用签名字节。我唯一的猜测是,为什么这不会搞砸任何事情,因为
接收的所有值都可能是正号。除了这是没有意义的,给定一个波形的幅度从[-1,1]变化。我要玩玩这个,试着弄清楚。如果存在负号,这里的代码实现似乎不会在ORing时移除
所以这都是错误的。我对它做了更多的思考,它真的很简单,实际上--这是一个这样的问题的唯一原因是因为我不知道big-endian,然后一旦我读到它,我误解了它是如何实现的。Endian-ness在下一个要点中解释了。 1
,因此我怀疑它不会对计算产生太大影响(假设我们处理的是非常大的值(
diff+=
意味着
diff
会非常大--给定代码及其所依赖的比较,额外的一些
1
应该不会影响结果)。
关于位的放置顺序,破坏声音等。我使用的代码设置bigendian=false
,这意味着字节顺序从最低有效字节到最高有效字节。由于这个原因,将buffer
的两个索引合并需要使用第二个索引,将其位放在第一位,并将第一个索引放在第二位(因此我们现在是按大端字节顺序)。我遇到的问题之一是“endian-ness”决定位序的印象。我以为10010101
big-endian会变成10101001
small-endian。事实证明,情况并非如此--每个字节中的位保持原来的顺序;不同的是字节是“向后”排序的。因此10110101 111000001
big-endian变为11100001 10110101
-每个字节内的位顺序相同;但是,不同的字节顺序。
/* The Javadoc explains that the targetDataLine will only read to a byte-typed array.
However, because the sample size is 16-bit, it is actually storing 16-bit numbers
there (shorts), auto-parsing them every eight bits. Additionally, because it is storing
them in little-endian, bits [2^0,2^7] are stored in index[i] in normal order (powers 76543210
)
while bits [2^8,2^15] are stored in index[i+1]. So, together they currently read as [7-6-5-4-3-2-1-0 15-14-13-12-11-10-9-8],
which is a problem. In the next for loop, we take care of this and re-organize the bytes by swapping every pair (remember the bits are ok, but the bytes are out of order).
Also, although the array is signed, this will not matter when we combine bytes, because the sign-bit (2^15) will be placed
back at the beginning like it normally is; although 2^7 currently exists as the most significant bit in its byte,
it is not a sign-indicating bit,
because it is really the middle of the short which was split. */
这是将以低字节第一字节顺序输入的字节流合并为以内部字节顺序输出的短消息流。
对于符号扩展,更多的是原始字节流的符号编码问题。如果原始字节流是无符号的(编码值从0到255),则克服了java将值视为有符号的不想要的影响。因此,受过教育的猜测是,外部字节流对无符号字节进行编码。
判断代码是否可信需要关于处理什么外部编码和使用什么内部编码的信息。例如。(胡乱猜测可能是完全错误的!):读取的两个字节垃圾可能属于一个立体声编码的两个通道,为了便于内部处理,它们被放入一个简单的简称中。您应该查看正在读取的编码以及应用程序中转换数据的使用情况。
我有办法转移arr元素: 当我执行这段代码时,我遇到了一个异常: 据我所知,程序需要更多的空间来包含另一个项目。但是我不需要添加更多的项目,我需要已经存在的移动。用参数,如果参数为负,所有数组向左移动,如果为正向右移动,如果为零-什么都不会发生。
问题内容: 我很难弄清楚如何移动数组元素。例如,给出以下内容: 我为什么能写入移动功能之前? 还是之后? 移动后,应更新其余元素的索引。这意味着在第一个示例中,移动后arr [0] =’a’,arr [1] =’d’arr [2] =’b’,arr [3] =’c’,arr [4] = ‘e’ 这似乎应该很简单,但是我无法将其包裹住。 问题答案: 如果您想在npm上使用一个版本,则array-mo
我做了一个代码,应该显示数组中元素排列的整个组合。 应该是什么: 123 213 231 132 312 321 但结果是这样的: 231 312 123 231 312 123 如何以应有的方式进行排列?
本文向大家介绍C ++程序中将两个数组按元素求和的位数变成一个新数组,包括了C ++程序中将两个数组按元素求和的位数变成一个新数组的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将编写一个程序来查找两个数组元素的太阳,并将它们存储到单独的数组中。 我们给出了两个数组,我们需要从两个数组中添加相应的索引元素。如果总和不是单个数字,则从数字中提取数字并将其存储在新数组中。 让我们来看一个例子
我有一个练习,找出出了什么问题。我会感激的帮助:) 编写将具有两个int类型数组和更大的返回数组(如果两个数组中的一个更大)以及与数组相同位置的元素的总和的代码。
问题内容: 在JavaScript中,我想不出代码来从n个数组(其中m个元素)中生成组合的代码。对于其他语言,我也曾见过类似的问题,但答案包含了我不确定如何翻译的语法或库魔术。 考虑以下数据: 3个数组,其中包含不同数量的元素。我想做的是通过组合每个数组中的一项来获得所有组合。 例如: 等等。 如果数组的数目是固定的,则很容易进行硬编码实现。但是数组的数量可能会有所不同: 任何帮助将非常感激。 问