- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言:Python
Package:pyaudio
官方網站
官方文件
功能:音訊的播放與錄製
close(stream)
terminate()
Host API
Device API
Stream Format Conversion
close()
Stream Info
Stream Management
Input Output
Package:pyaudio
官方網站
官方文件
功能:音訊的播放與錄製
基本知識
- sampling rate
- 類比訊號轉成數位訊號的取樣率
- bit depth
- 用多少 bit 表現一個 sample
- channel
- 聲道
- 1 => mono 為單聲道
2 => stereo 為雙聲道或又稱立體聲 - frame
- 構成一個聲音的最小單位
即是一組 samples。與 channel 相關 - 單聲道 ( mono ) = 1 sample = 1 frame
雙聲道 ( stereo) = 2 samples = 1 frame
5.1聲道(左, 中央, 右, 右後, 左後, 低音) = 6 samples = 1 frame - frame size = bit depth * channels
Blocking 範例
''' 播放特定頻率 ''' import numpy as np import pyaudio def sine(frequency, t, sampleRate): ''' 產生 sin wave :Args: - frequency: 欲產生的頻率 Hz - t: 播放時間長度 seconds - sampleRate: 取樣頻率 1/s ''' # 播放數量 n = int(t * sampleRate) # 每秒轉動的角度再細分為取樣間隔 interval = 2 * np.pi * frequency / sampleRate return np.sin(np.arange(n) * interval) def play_tone(stream, frequency=440, t=1, sampleRate=44100): ''' 播放特定頻率 :Args: - stream: - frequency: 欲產生的頻率 Hz - t: 播放時間長度 seconds - sampleRate: 取樣頻率 1/s ''' data = sine(frequency, t, sampleRate) # 因 format 為 pyaudio.paFloat32,故轉換為 np.float32 並轉換為 bytearray stream.write(data.astype(np.float32).tostring()) if __name__ == '__main__': p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True) play_tone(stream, frequency=1000, #Hz t=3) #seconds stream.close() p.terminate()
Non-Blocking 範例
''' non-blocking 播放特定頻率 ''' import numpy as np import pyaudio import time # frames CHUNK = 1024 # channels CH = 1 def sine(frequency, t, sampleRate): ''' 產生 sin wave :Args: - frequency: 欲產生的頻率 Hz - t: 播放時間長度 seconds - sampleRate: 取樣頻率 1/s ''' # 播放數量 n = int(t * sampleRate) # 每秒轉動的角度再細分為取樣間隔 interval = 2 * np.pi * frequency / sampleRate return np.sin(np.arange(n) * interval) def sliceData(frame_count, channels): ''' 切出合適的長度,也就是 frame_count * channels * sampleBytes :Args: - frame_count: frames 的數目 - channels: channels 數目 ''' data = sine(frequency=1000, t=3, sampleRate=44100) # 因會再轉換為 np.float32,故無需乘上 sampleBytes size = channels * frame_count while True: dataSlice = data[:size] # 此時小數點會用 np.float32 4byte 表示,故資料長度會變為 4 倍 dataBytes = dataSlice.astype(np.float32).tostring() yield dataBytes # 刪除已輸出資料 data = np.delete(data, range(size)) dataGen = sliceData(CHUNK, CH) def callback(in_data, frame_count, time_info, status): global dataGen data = next(dataGen) return (data, pyaudio.paContinue) if __name__ == '__main__': p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paFloat32, channels=CH, rate=44100, output=True, frames_per_buffer=CHUNK, stream_callback=callback) # stream.start_stream() for i in range(1000): print(i) stream.stop_stream() stream.close() p.terminate()
Module pyaudio
- Classes
- pyaudio.PyAudio
- pyaudio.Stream
- Host Specific Classes
- pyaudio.PaMacCoreStreamInfo
- Stream Conversion Convenience Functions
- pyaudio.get_sample_size(format)
- 指定格式的大小 (bytes)
- format
- 即是下面的 Portaudio Sample Formats
- pyaudio.get_format_from_width(width, unsigned=True)
- 指定 sample 大小的格式
- 除 pyaudio.paInt32 以外的格式
- width
- byte 單位,可為 1, 2, 3, 4
- unsigned
- 有無負值
- PortAudio version
- pyaudio.get_portaudio_version()
- portaudio 版本 (Int)
- "19.5.1" 會得到 16進位 0x00130501
- pyaudio.get_portaudio_version_text()
- portaudio 版本 (String)
- Portaudio Sample Formats
- pyaudio.paFloat32 = 1
- pyaudio.paInt32 = 2
- pyaudio.paInt24 = 4
- pyaudio.paInt16 = 8
- pyaudio.paInt8 = 16
- pyaudio.paUInt8 = 32
- pyaudio.paCustomFormat = 65536
- PortAudio Host APIs
- pyaudio.paInDevelopment
- Still in development
- pyaudio.paDirectSound
- DirectSound (Windows only)
- pyaudio.paMME
- Multimedia Extension (Windows only)
- pyaudio.paASIO
- Steinberg Audio Stream Input/Output
- pyaudio.paSoundManager
- SoundManager (OSX only)
- pyaudio.paCoreAudio
- CoreAudio (OSX only)
- pyaudio.paOSS
- Open Sound System (Linux only)
- pyaudio.paALSA
- Advanced Linux Sound Architecture (Linux only)
- pyaudio.paAL
- Open Audio Library
- pyaudio.paBeOS
- BeOS Sound System
- pyaudio.paWDMKS
- Windows Driver Model (Windows only)
- pyaudio.paJACK
- JACK Audio Connection Kit
- pyaudio.paWASAPI
- Windows Vista Audio stack architecture
- pyaudio.paNoDevice
- Not actually an audio device
- PortAudio Error Codes
- pyaudio.paNoError
- pyaudio.paNotInitialized
- pyaudio.paUnanticipatedHostError
- pyaudio.paInvalidChannelCount
- pyaudio.paInvalidSampleRate
- pyaudio.paInvalidDevice
- pyaudio.paInvalidFlag
- pyaudio.paSampleFormatNotSupported
- pyaudio.paBadIODeviceCombination
- pyaudio.paInsufficientMemory
- pyaudio.paBufferTooBig
- pyaudio.paBufferTooSmall
- pyaudio.paNullCallback
- pyaudio.paBadStreamPtr
- pyaudio.paTimedOut
- pyaudio.paInternalError
- pyaudio.paDeviceUnavailable
- pyaudio.paIncompatibleHostApiSpecificStreamInfo
- pyaudio.paStreamIsStopped
- pyaudio.paStreamIsNotStopped
- pyaudio.paInputOverflowed
- pyaudio.paOutputUnderflowed
- pyaudio.paHostApiNotFound
- pyaudio.paInvalidHostApi
- pyaudio.paCanNotReadFromACallbackStream
- pyaudio.paCanNotWriteToACallbackStream
- pyaudio.paCanNotReadFromAnOutputOnlyStream
- pyaudio.paCanNotWriteToAnInputOnlyStream
- pyaudio.paIncompatibleStreamHostApi
- PortAudio Callback Return Codes
- pyaudio.paContinue
- There is more audio data to come
- pyaudio.paComplete
- This was the last block of audio data
- pyaudio.paAbort
- An error ocurred, stop playback/recording
- PortAudio Callback Flags
- pyaudio.paInputUnderflow
- Buffer underflow in input
- pyaudio.paInputOverflow
- Buffer overflow in input
- pyaudio.paOutputUnderflow
- Buffer underflow in output
- pyaudio.paOutputOverflow
- Buffer overflow in output
- pyaudio.paPrimingOutput
- Just priming, not playing yet
class pyaudio.PyAudio
- 利用此 class 開關 streams
- Stream Management
- open(rate, channels, format, input=False, output=False, input_device_index=None, output_device_index=None, frames_per_buffer=1024, start=True, input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None, stream_callback=None)
- rate
- 取樣率 (Hz)
- channels
- channels 數目
- format
- 即是上面的 Portaudio Sample Formats
- input
- 是否為 input
- output
- 是否為 output
- input_device_index
- 輸入裝置的 index,None 表預設
- output_device_index
- 輸出裝置的 index,None 表預設
- frames_per_buffer
- buffer 共有多少 frames
- start
- stream 是否立即開始
- input_host_api_specific_stream_info
- 使用在 PaMacCoreStreamInfo
- output_host_api_specific_stream_info
- 使用在 PaMacCoreStreamInfo
- stream_callback
- 運用在 non-blocking
- Function 格式如下
def callback(in_data, # 若 input=True 則傳進錄製的資料,不然為 None frame_count, # number of frames time_info, # dictionary status_flags)# PortAudio Callback Flags # 不可使用 Stream.read() or Stream.write() # out_data 長度應為 frame_count * channels * sampleBytes return (out_data, flag)
- 通常使用 Stream.close()
- 中斷 PortAudio 釋放資源
- get_host_api_count()
- Host API 的總數量
- get_default_host_api_info()
- 預設 Host API 的資訊
- get_host_api_info_by_type(host_api_type)
- 指定 Host API 的資訊
- host_api_type
- 即是上面的 PortAudio Host APIs
- get_host_api_info_by_index(host_api_index)
- 指定 Host API 的資訊
- host_api_index
- 第幾個 Host API
- get_device_info_by_host_api_device_index(host_api_index, host_api_device_index)
- 指定 Host API 的指定裝置資訊
- host_api_index
- 第幾個 Host API
- host_api_device_index
- Host API 的第幾個裝置
- get_device_count()
- 裝置的總數量
- is_format_supported(rate, input_device=None, input_channels=None, input_format=None, output_device=None, output_channels=None, output_format=None)
- 格式是否支援
- rate
- 取樣率 (Hz)
- input_device
- 輸入裝置的 index
- input_channels
- 輸入 channels 數目
- input_format
- 輸入格式
- output_device
- 輸出裝置的 index
- output_channels
- 輸出 channels 數目
- output_format
- 輸出格式
- get_default_input_device_info()
- 預設輸入裝置的資訊
- get_default_output_device_info()
- 預設輸出裝置的資訊
- get_device_info_by_index(device_index)
- 指定裝置的資訊
- device_index
- 第幾個裝置
- get_sample_size(format)
- 指定格式的大小 (bytes)
- format
- 即是上面的 Portaudio Sample Formats
- get_format_from_width(width, unsigned=True)
- 指定 sample 大小的格式
- 除 pyaudio.paInt32 以外的格式
- width
- byte 單位,可為 1, 2, 3, 4
- unsigned
- 有無負值
class pyaudio.Stream
- PortAudio Stream Wrapper
- 需用 PyAudio.open() 建立
- Opening and Closing
- __init__(PA_manager, rate, channels, format, input=False, output=False, input_device_index=None, output_device_index=None, frames_per_buffer=1024, start=True, input_host_api_specific_stream_info=None, output_host_api_specific_stream_info=None, stream_callback=None)
- 必須由 PyAudio.open() 呼叫,可為 input or output 甚至皆可
- PA_manager
- PyAudio instance
- rate
- 取樣率 (Hz)
- channels
- channels 數目
- format
- 即是上面的 Portaudio Sample Formats
- input
- 是否為 input
- output
- 是否為 output
- input_device_index
- 輸入裝置的 index,None 表預設
- output_device_index
- 輸出裝置的 index,None 表預設
- frames_per_buffer
- buffer 共有多少 frames
- start
- stream 是否立即開始
- input_host_api_specific_stream_info
- 使用在 PaMacCoreStreamInfo
- output_host_api_specific_stream_info
- 使用在 PaMacCoreStreamInfo
- stream_callback
- 運用在 non-blocking
- Function 格式如下
def callback(in_data, # 若 input=True 則傳進錄製的資料,不然為 None frame_count, # number of frames time_info, # dictionary status_flags)# PortAudio Callback Flags # 不可使用 Stream.read() or Stream.write() # out_data 長度應為 frame_count * channels * sampleBytes return (out_data, flag)
- 關閉 stream
- get_input_latency()
- input 延遲
- get_output_latency()
- output 延遲
- get_time()
- stream 時間
- get_cpu_load()
- CPU 使用率,只適用於 non-blocking
- start_stream()
- 開始執行 stream
- stop_stream()
- 停止執行 stream
- is_active()
- stream 是否啟動
- is_stopped()
- stream 是否停止
- write(frames, num_frames=None, exception_on_underflow=False)
- 寫入資料於 stream
- 不可使用在 non-blocking mode
- frames
- 寫入的資料
- num_frames
- 寫入的 frames 數目,None 表示自動計算
- exception_on_underflow
- underflow 是否丟出 exception
- read(num_frames, exception_on_overflow=True)
- 從 stream 讀取資料
- 不可使用在 non-blocking mode
- num_frames
- 讀取的 frames 數目
- exception_on_overflow
- overflow 是否丟出 exception
- get_read_available()
- 無需等待的可讀 frames 數目
- get_write_available()
- 無需等待的可寫 frames 數目
感謝您的分享!我參考您的程式碼寫了產生雙音多頻訊號的程式,這是我寫的筆記 https://keejko.blogspot.com/2019/08/python.html
回覆刪除