如何打印充满“混乱问号”的字符串值

2 投票
4 回答
1056 浏览
提问于 2025-04-18 01:48

我正在用Python调试音频,遇到了音频编码方面的困难。

这里有一串音频数据,比如说是[10, 20, 100]。

不过这些数据是存储在一个字符串变量里的,

data = "����������������"

我想查看这个字符串里的值。

下面是我尝试过的几种方法:

以整数形式打印

我试着用 print "%i" % data[0] 来打印,结果是

 Traceback (most recent call last):
   File "wire.py", line 28, in <module>
     print "%i" % data[i]
 TypeError: %d format: a number is required, not str

转换为整数

int(data[0]) 转换,结果是

Traceback (most recent call last):
  File "wire.py", line 27, in <module>
    print int(data[0])
ValueError: invalid literal for int() with base 10: '\xd1'

有没有什么好的建议?我想以数字的方式打印这个字符串,因为它实际上是一个声音波形的数组。

编辑

你们的回答都非常有帮助。

这个字符串实际上是从麦克风生成的,所以我认为它是原始的波形数据,或者说是振动数据。进一步的内容可以参考音频API文档,PortAudio

在查看PortAudio后,我发现了一个很有用的例子。

** This routine will be called by the PortAudio engine when audio is needed.
** It may called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
static int patestCallback( const void *inputBuffer, void *outputBuffer,
                            unsigned long framesPerBuffer,
                            const PaStreamCallbackTimeInfo* timeInfo,
                            PaStreamCallbackFlags statusFlags,
                            void *userData )
{
    paTestData *data = (paTestData*)userData;
    float *out = (float*)outputBuffer;
    unsigned long i;

    (void) timeInfo; /* Prevent unused variable warnings. */
    (void) statusFlags;
    (void) inputBuffer;

    for( i=0; i<framesPerBuffer; i++ )
    {
        *out++ = data->sine[data->left_phase];  /* left */
        *out++ = data->sine[data->right_phase];  /* right */
        data->left_phase += 1;
        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
    }

    return paContinue;
}

这表明我可以以 float 的形式来解释这些数据。

4 个回答

0

如果你使用新的 {}.format 方法会更好:

data = "����������������"

print '{0}'.format(data[3])
0

你可以使用 ord 函数来把每个字节转换成它在0到255之间的数字值:

print map(ord, data)

或者,为了兼容Python 3,可以这样做:

print([ord(c) for c in data])

这个方法也可以用于Unicode字符,但这可能不是你想要的,所以确保你在Python 2中使用的是字节数组,或者是一个真正的 strbytes 对象。

1

如果你对上面提到的 \xd1 没问题的话:

for item in data: print repr(item), 

要注意的是,使用 for x in data 这个写法会一个一个地遍历列表里的每个值,而不是它们的位置。如果你想要获取位置,可以用 for i in range(len(data)): ... 这样的写法。

如果你想要数字形式的值,可以把 repr(item) 替换成 ord(item)

3

首先要明确,你的音频数据是一个字节字符串。这个字节字符串就是音频文件中存储的字节的表现形式。你不能仅仅把这些字节转换成有意义的值,而不先了解这些字节的具体内容。

举个例子,mp3的规范说明每个mp3文件都有头部帧(可以在这里查看详细信息:http://en.wikipedia.org/wiki/MP3)。要读取这个头部,你可以使用像bitstring这样的工具,或者如果你对位运算比较熟悉,也可以自己动手解包一个整数(4个字节),然后通过一些数学运算来找出32个单独位的值。

这其实完全取决于你想读取什么,以及这些数据是怎么生成的。如果你有完整的字节数,那么使用struct会非常合适。

撰写回答