json文件只能采用整数或切片格式,不能采用字符串

时间:2018-07-09 10:51:30

标签: python

我在运行下面的代码时遇到问题,在t one_freq = tone_map [tone_name ”行,它会导致错误,即列表索引必须是整数或切片而不是字符串

评论的音调网站上的Json示例是

[
 {
   "432": "Note",
   "434": "Frequency (Hz)",
   "436": "Wavelength (cm)",
   "438": "",
   "440": "",
   "442": "",
   "444": "",
   "446": ""
  },
 {
   "432": "C0",
   "434": "16.35",
   "436": "2109.89",
   "438": "",
   "440": "",
   "442": "",
   "444": "",
   "446": ""
  },
 {
   "432": "C#0/Db0",
   "434": "17.32",
   "436": "1991.47",
   "438": "",
   "440": "",
   "442": "",
   "444": "",
   "446": ""
  },

我用来合成音调以生成音乐的python代码是这个。我已将http://www.phy.mtu.edu/~suits/notefreqs.html处的html表转换为正在使用的json文件,但说它必须是整数或切片

import json

import numpy as np
import matplotlib.pyplot as plt
from scipy.io.wavfile import write

# Synthesize the tone based on the input parameters
def tone_synthesizer(freq, duration, amplitude=1.0, sampling_freq=44100):
# Construct the time axis 
    time_axis = np.linspace(0, duration, duration * sampling_freq)

# Construct the audio signal
    signal = amplitude * np.sin(2 * np.pi * freq * time_axis)

    return signal.astype(np.int16) 

if __name__=='__main__':
    # Names of output files
    file_tone_single = 'generated_tone_single.wav'
    file_tone_sequence = 'generated_tone_sequence.wav'

    # Source: http://www.phy.mtu.edu/~suits/notefreqs.html
    mapping_file = 'tone_mapping.json'

   # Load the tone to frequency map from the mapping file
with open(mapping_file, 'r') as f:
    tone_map = json.loads(f.read())

# Set input parameters to generate 'F' tone
tone_name = 'F'
duration = 3     # seconds
amplitude = 12000
sampling_freq = 44100    # Hz

# Extract the tone frequency
tone_freq = tone_map[tone_name]

# Generate the tone using the above parameters
synthesized_tone = tone_synthesizer(tone_freq, duration, amplitude, sampling_freq)

# Write the audio signal to the output file
write(file_tone_single, sampling_freq, synthesized_tone)

# Define the tone sequence along with corresponding durations in seconds
tone_sequence = [('G', 0.4), ('D', 0.5), ('F', 0.3), ('C', 0.6), ('A', 0.4)]

# Construct the audio signal based on the above sequence 
signal = np.array([])
for item in tone_sequence:
    # Get the name of the tone 
    tone_name = item[0]

    # Extract the corresponding frequency of the tone
    freq = tone_map[tone_name]

    # Extract the duration
    duration = item[1]

    # Synthesize the tone
    synthesized_tone = tone_synthesizer(freq, duration, amplitude, sampling_freq)

    # Append the output signal
    signal = np.append(signal, synthesized_tone, axis=0)

# Save the audio in the output file
write(file_tone_sequence, sampling_freq, signal)

2 个答案:

答案 0 :(得分:1)

来自python文档:

  

json.loads(s [,encoding [,cls [,object_hook [,parse_float [,parse_int [,parse_constant [,object_pairs_hook [,** kw]]]]]]]]]]]))

     

使用此转换表将s(包含JSON文档的str或unicode实例)反序列化为Python对象。

     

如果s是一个str实例,并且使用UTF-8(例如latin-1)以外的基于ASCII的编码进行编码,则必须指定适当的编码名称。不允许使用非基于ASCII的编码(例如UCS-2),并且应先将其解码为unicode。

从错误中您可以了解,tone_map是一个列表。 试试这个:

for i in tone_map: tone_freq = i[tone_name]

将tone_freq存储在列表中并使用它

tone_frequencies = list() for i in tone_map: tone_frequencies.append(i)

答案 1 :(得分:0)

无论您将HTML表(http://www.phy.mtu.edu/~suits/notefreqs.html)转换为JSON的方式是什么,似乎都是以这种格式为您带来了极大的不便。如果查看JSON文档,则它是一个数组(不是map / dict)。数组元素似乎与原始表行相对应,每个数组元素本身都是字典,包含键“ 432”,“ 434”,“ 436”,“ 438”等。其中的前三个是表的三列(名称,频率,波长),其余为空。

您首先应该尝试将其重新设置为更有用的格式,例如,音符名称和频率之间的映射(不要忘记将频率数据转换为浮点数-JSON文档将其作为字符串)。也许像这样的事情会做:

name_column="432"
freq_column="434"
fmap = { row[name_column] : float(row[freq_column]) for row in json_doc[1:] }

(请注意,我已经切掉了第一个数组元素,其中包含列名)

现在,您可以尝试:

freq = fmap["E0"]
print (freq)

此外,在示例Python代码中,您使用的注释名称如“ C”,但在表中找不到该名称(它具有“ C0”,“ C1”等)。