シュウジマブログ

Apple製品,技術系の話をするブログ

オーディオ用減衰器(電子ボリューム) LM1972MをRaspberry Pi (Python)で動かす

Keyword : LM1972M オーディオ 電子ボリューム アッテネータ 減衰 オペアンプ Raspberry Pi 3 Python 2 spidev python-spi

環境

回路

LM1972Mを含むオーディオミキサを製作しました. f:id:masa_flyu:20180927212748j:plain 3入力のオーディオミキサになっており,全ての入力に手動のボリュームが,うち1つの入力に電子ボリュームが入っています.

なお,この回路は真似しない方がいいです.LM1972Mとは無関係なところで,音質がめっちゃ悪かったので...

また,音量の切り替えの際にノイズが乗ります.これを防ぐ方法があるかは不明です.

一応LM1972Mに関わるところで,この回路はオーディオ入出力をコンデンサで直流絶縁し,0[V]になる点をGNDと分離しています.

nabe.adiary.jp

こちらにあるように単純なレールスプリッタで電源の中間電位(12[V]電源なのでおよそ6[V] )をオーディオ回路の0[V]電位としています.

LM1972MはロジックのGNDとアナログのGNDが分かれているため,それぞれ異なる電位に設定しています.

Raspberry Piとは * LOGIC_GND → GND (25番ピンなど) * CLOCK → GPIO 11 (SCKL, 23番ピン) * LOAD/SHIFT → GPIO24 (CE0, 24番ピン) * DATA-IN → GPIO10 (MOSI, 19番ピン) * DATA-OUT → GPIO9 (MISO, 21番ピン) の5本を接続します.

f:id:masa_flyu:20180927210204p:plain

Raspberry Piの準備

spidevをインストールします.

インストール手順は,こちらの記事が参考になります.

qiita.com

spidevのインストールさえできれば,以下のコードが動くはずです.

コード

訳あってPython2で書きました.

#!/usr/bin/env python2
# This is a python 2 program for LM1972M and Raspberry Pi
# (c) shujima1 , 2018

import spidev
import time

# Setup
spi = spidev.SpiDev()
spi.open(0,0) # 0 Channel

spi.max_speed_hz = 1000000 #[Hz]
spi.mode = 0b11 #SPI Mode 3

att = 0
cnt = 0

while True:
    if ( cnt % 400 < 100 ): # volume max
      att = 0
    elif ( cnt % 400 < 200 ): # volume down
      att = ( cnt % 400 - 100 )
    elif ( cnt % 400 < 300 ): # muted
      att = 127
    else: # volume up
      att = 100 - ( cnt % 400 - 300 )
    
    # Byte 0 : Channel , Byte 1 : Value
    resp = spi.xfer2([0,att]) #Channel 0
    resp = spi.xfer2([1,att]) #Channel 1
    
    print "Count: " , cnt , ",  Value:" , att , ",  Attenuation: " ,  
    if ( att != 127 ):
      print -att/2 , " [dB]"
    else:
      print "Muted"
    
    cnt += 1
    time.sleep(0.05)

コードの説明

このコードを実行すると,オーディオの音量がMAXからだんだん小さくなりMuteに,今度はMuteから音量が大きくなりMAXに,を繰り返します.

以下コードを部分ごとに分けてざっくり解説します.

# Setup
spi = spidev.SpiDev()
spi.open(0,0) # 0 Channel

spi.max_speed_hz = 1000000 #[Hz]
spi.mode = 0b11 #SPI Mode 3

SPIの設定をしています.今回はCE0の方に接続しています. モードや速度はデータシートを参照してください.

    if ( cnt % 400 < 100 ): # volume max
      att = 0
    elif ( cnt % 400 < 200 ): # volume down
      att = ( cnt % 400 - 100 )
    elif ( cnt % 400 < 300 ): # muted
      att = 127
    else: # volume up
      att = 100 - ( cnt % 400 - 300 )

変数cntは常に増加し続けます.cntの値に合わせて変数attを台形波状に0〜127の間で変動させます.

    # Byte 0 : Channel , Byte 1 : Value
    resp = spi.xfer2([0,att]) #Channel 0
    resp = spi.xfer2([1,att]) #Channel 1
    
    print "Count: " , cnt , ",  Value:" , att , ",  Attenuation: " ,  
    if ( att != 127 ):
      print -att/2 , " [dB]"
    else:
      print "Muted"

spi.xfer2(spidevの仕様を参照)関数を用いて,[0,att]の2バイト,続けて[1,att]の2バイトを送っています.これは,LM1972Mが備える2つの入力の音量を同時に変化させているためです.

attは音量の減衰量で,0〜-47.5[dB]の間は0.5[dB]刻みで減少します.-47.5[dB]も減衰させればほぼ完全な無音なため,ここでは,それより下を気にせず,-att/2 [dB]として表示しています.

またattの値を127に設定すると完全なMuteになります.

おまけ,

python3 コード(print行が違うだけ)

#!/usr/bin/env python3
# This is a python 3 program for LM1972M and Raspberry Pi
# (c) shujima1 , 2018

import spidev
import time

# Setup
spi = spidev.SpiDev()
spi.open(0,0) # 0 Channel

spi.max_speed_hz = 1000000 #[Hz]
spi.mode = 0b11 #SPI Mode 3

att = 0
cnt = 0

while True:
    if ( cnt % 400 < 100 ): # volume max
      att = 0
    elif ( cnt % 400 < 200 ): # volume down
      att = ( cnt % 400 - 100 )
    elif ( cnt % 400 < 300 ): # muted
      att = 127
    else: # volume up
      att = 100 - ( cnt % 400 - 300 )
    
    # Byte 0 : Channel , Byte 1 : Value
    resp = spi.xfer2([0,att]) #Channel 0
    resp = spi.xfer2([1,att]) #Channel 1
    
    print ( "Count: " , cnt , ",  Value:" , att , ",  Attenuation: " , end="" )
    if ( att != 127 ):
      print (-att/2 , " [dB]" )
    else:
      print ("Muted")
    
    cnt += 1
    time.sleep(0.05)
当ブログをご利用いただく際には免責事項をお読みください。