4 回答

TA貢獻1877條經驗 獲得超1個贊
根據您的評論,您想一點一點地處理二進制數據,將每一位變成高音或低音。
您仍然需要確切地確定那些高低音是什么,每個聲音聽起來要持續多長時間(以及兩者之間是否有間隔等等)。如果您將其放慢,例如每個聲音1/4秒,則將它們視為音符。如果您使其速度非常快(例如1/44100秒),則將其視為樣本。人耳在一秒鐘內聽不到44100種不同的聲音;相反,它會聽到高達22050Hz的聲音。
做出這些決定后,問題將分為兩個部分。
首先,您必須生成一個樣本流,例如,每秒要生成44100個16位整數流。對于非常簡單的事情,例如以44k 16位單聲道格式播放原始PCM文件的一部分,或生成方波,這是微不足道的。對于更復雜的情況,例如播放MP3文件的一部分或通過正弦波和濾波器合成聲音,則需要一些幫助。該audioop模塊以及stdlib中的其他一些模塊可以為您提供基礎知識。除此之外,您需要在PyPI中搜索適當的模塊。
其次,您必須將樣本流發送到耳機插孔。Python沒有對此的內置支持。在某些平臺上,只需打開一個特殊文件并對其進行寫入,即可完成此操作。但是,更一般而言,您將需要在PyPI上找到第三方庫。
較簡單的模塊適用于一種特定類型的音頻系統。Mac和Windows都有各自的標準,Linux有六個不同的標準。還有一些Python模塊與高層包裝器通信。您可能必須安裝并設置包裝程序,但是一旦完成,代碼就可以在任何系統上運行。
因此,讓我們來看一個非常簡單的示例。假設您已經在系統上設置了PortAudio,并且已經安裝了PyAudio與之對話。該代碼將播放441Hz和220.5Hz的方波(僅在中C和低C之上)不到1/4秒(僅因為這很容易)。
import binascii
a = open('/Users/kyle/Desktop/untitled folder/unix commands.txt', 'r')
c = a.read()
b = bin(int(binascii.hexlify(c), 16))
sample_stream = []
high_note = (b'\xFF'*100 + b'\0'*100) * 50
low_note = (b'\xFF'*50 + b'\0'*50) * 100
for bit in b[2:]:
if bit == '1':
sample_stream.extend(high_note)
else:
sample_stream.extend(low_note)
sample_buffer = b''.join(sample_stream)
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(8),
channels=1,
rate=44100,
output=True)
stream.write(sample_buffer)

TA貢獻1998條經驗 獲得超6個贊
因此,您想使用音頻傳輸數字信息嗎?基本上,您想在軟件中實現MODEM(無論它是純軟件,還是稱為調制解調器)。
調制解調器(MOdulator-DEModulator)是一種對模擬載波信號進行調制以對數字信息進行編碼的設備,還對此類載波信號進行解調以對所傳輸的信息進行解碼的設備。目標是產生一個易于傳輸和解碼的信號,以再現原始數字數據。調制解調器可用于從發光二極管到無線電的任何傳輸模擬信號的方式。[維基百科]
您到處都需要通過模擬媒體傳輸數據的調制解調器,無論是聲音,光波還是無線電波。您的電視遙控器可能是紅外調制解調器。
用純軟件實現的調制解調器稱為軟調制解調器。我在野外看到的大多數軟調制解調器都在使用某種形式的FSK調制:
頻移鍵控(FSK)是一種調頻方案,其中通過載波的離散頻率變化來發送數字信息。1最簡單的FSK是二進制FSK(BFSK)。BFSK使用一對離散頻率來傳輸二進制(0和1s)信息。2在該方案中,“ 1”稱為標記頻率,“ 0”稱為空間頻率。右圖顯示了FSK調制載波的時域。[維基百科]
通過聲波通過大氣傳輸數據的應用非常有趣-我想這是shopkick用來驗證用戶是否存在的東西。
對于Python,請檢查GnuRadio項目。
對于C庫,請查看Steve Underwood的工作(但請不要在愚蠢的問題上與他聯系)。我用他的軟調制解調器來引導一個傳真到郵件網關的星號(傳真傳輸是不是比B / W更TIFF音頻通過電話線編碼進行傳輸文件)。

TA貢獻1848條經驗 獲得超6個贊
因此,這是Abarnert的代碼,已更新為python3。
import binascii
import pyaudio
a = open('/home/ian/Python-programs/modem/testy_mcTest.txt', 'rb')
c = a.read()
b = bin(int(binascii.hexlify(c), 16))
sample_stream = []
high_note = (b'\xFF'*100 + b'\0'*100) * 50
low_note = (b'\xFF'*50 + b'\0'*50) * 100
for bit in b[2:]:
if bit == '1':
sample_stream.extend(high_note)
else:
sample_stream.extend(low_note)
sample_buffer = ''.join(map(str, sample_stream))
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(1),
channels=1,
rate=44100,
output=True)
stream.write(sample_buffer)
# stop stream (4)
stream.stop_stream()
stream.close()
# close PyAudio (5)
p.terminate()
添加回答
舉報