2014-07-22 175 views
2

我有一個函數用於創建Python中的方波,我似乎無法得到一個聲音出來,但是當我改變這樣的:Python方波函數 - 這裏發生了什麼?

value = state * volume 
s.append([value, value]) 

這樣:

value = state * volume 
s.append([0, value]) 

我聽到了一個聲音,但它的頻率遠高於我打算製作的130.81頻率。下面是完整的代碼:

elif current_type == SQUARE_WAVE_TYPE: 

      if event.type == KEYDOWN: 

       #lower notes DOWN 

       if event.key == K_z: 
        print current_type, 130.81 
        #current_played['z'] = MakeSineWave(80.81) 
        current_played['z'] = MakeSquareWave(130.81) 
        current_played['z'].play(-1) 

       elif event.key == K_c: 
        print current_type, 180.81 
        #current_played['c'] = MakeSineWave(80.81) 
        current_played['c'] = MakeSquareWave(180.81) 
        current_played['c'].play(-1) 

任何人都可以看到,爲什麼這種情況正在發生:

def SquareWave(freq=1000, volume=10000, length=1): 

    num_steps = length * SAMPLE_RATE 
    s = [] 

    length_of_plateau = SAMPLE_RATE/(2*freq) 

    counter = 0 
    state = 1 

    for n in range(num_steps): 

     value = state * volume 
     s.append([value, value]) 

     counter += 1 

     if counter == length_of_plateau: 
      counter = 0 
      state *= -1 

    return numpy.array(s) 

def MakeSound(arr): 
    return pygame.sndarray.make_sound(arr) 

def MakeSquareWave(freq=1000): 
    return MakeSound(SquareWave(freq)) 

的代碼調用這些功能如下塊?這個方波函數實際上是否正確?

+0

循環內'counter'與'length_of_plateau'的值是多少?您可以調試代碼並找到這兩個值的具體示例嗎? –

+1

使用'print value'來查看你有什麼值。 – furas

+3

我問的原因是我懷疑'length_of_plateau'是一個浮點值,而'counter'是一個整數,因此當頻率爲130.81時,它們在任何點都相等的機會根本就沒有,或者可能一次藍色月亮更正確。無論如何,請驗證這些變量的值,看看它是否與我在這裏說的相符。 –

回答

2

您的問題的原因很可能是因爲您沒有正確考慮浮點值。

藉此比較:

if counter == length_of_plateau: 

此相比counter,的整數,length_of_plateau,一個浮點值。

length_of_plateau從這個分配傳來:

length_of_plateau = SAMPLE_RATE/(2*freq) 

憑藉130.81的頻率,以及44100的採樣率(我猜在這裏,你沒有張貼什麼SAMPLE_RATE的值),你得到這樣的:

length_of_plateau = 168.565094412 

所以,整數將永遠不等於該值。

相反,這裏就是我會做:

state = 1 
next_plateau_end = length_of_plateau 

counter = 0 
for n in range(num_steps): 
    value = state * volume 
    s.append([value, value]) 

    if counter >= next_plateau_end: 
     counter -= length_of_plateau 
     state *= -1 
    counter += 1 

而是每次重新counter爲0,而不是我們減去了高原的長度(這是一個浮點值)。這意味着在原始代碼中引入的舍入錯誤將隨着時間的推移而被平滑掉。

+0

我並不完全確定添加'[value,value]'的意義是什麼,如果這樣會將兩個值添加到輸出中,您沒有獲得正確的頻率,但是您在這裏最好判斷什麼是正確的。我100%確定浮點問題是使程序生成不正確的波形。 –

+0

不錯的答案,你也可以寫一個函數來計算給定採樣率下的誤差。 –

+0

我會對此進行一次更改 - 而不是'next_plateau_end + = length_of_plateau',我會做'n - = length_of_plateau'。這樣做的原因是,如果它被移植到C,那麼'n'將是一個有限整數類型。如果這個有限整數類型是16位或32位,按照目前的寫法,完全可能'n'會在合理的時間內(在44100Hz,2^31採樣〜= 13.5小時)溢出。在溢出時,一個週期會變形。 不是說我犯了這個錯誤,哦不。 – mtrw

相關問題