@AnderBiguri 非常成功。获取您的数组,将其转换为有符号双精度,规范化并播放它。
由于您有一个n x 16 矩阵,其中每一行是一个样本,每一列是该数字的一个位,首先我们需要将该矩阵转换为双精度格式。我们可以使用bin2dec 来帮助我们做到这一点。但是,bin2dec 接受string。因此,我们可以像这样将矩阵转换为字符串数组。假设inSound 包含您之前指定的声音矩阵。
我还将假设您的位是 Big-Endian 格式,因此最高有效位是最左边的位,然后是最右边的位。
根据你们的 cmets,数字是 1 的恭维符号。这意味着如果最高有效位为 1,我们只需反转整个数字。因此,我们可以通过检查整个第一列以查看是否存在1 或0 来确定哪些行是负数。我们找到带有1 的行,然后简单地取1 并减去数组中的每个元素。因此:
checkSign = inSound(:,1) == 1;
inSound(checkSign,:) = 1 - inSound(checkSign,1);
因此,当我们将数字转换为十进制时,我们只需再次找到那些应该为负数的行并将它们取反即可。让我们先转换我们的数字。
inSoundString = char(inSound + '0');
char 将矩阵或向量中的每个数字转换为其字符串表示形式,假设char 的输入是ASCII 代码。因此,当我们添加0 时,我们将inSound 中的每个数字与代表0 在ASCII 中的数字ASCII 代码相加。这是我们开始的基线。之后,inSound 会将0 或1 添加到此数字代码中,这样当我们将整个矩阵转换为字符串时,我们最终将获得这些数字的 string 表示。
现在将二进制字符串转换为实际数字:
outSoundDec = bin2dec(inSoundString);
这将获取每一行并将其转换为等效的十进制数。现在,如果您的位在 Little-Endian 中,您可以使用 swapbytes 翻转位,以便在继续之前将位转换为 Big-Endian。现在我们已经转换了我们的数字,我们需要否定那些应该是负数的行。
这样:
outSoundDec(checkSign) = -outSoundDec(checkSign);
现在我们需要对其进行规范化,使范围在-1 到1 之间。鉴于您已指定范围在[-32768, 32767] 之间,我们只需将所有数字除以32768。因此:
outSound = outSoundDec / 32768;
上面的代码现在将规范化您的信号,使其从-1 变为1。您可以使用sound(outSound, Fs); 播放您的声音,其中Fs 是您获得信号的采样频率。
祝你好运!