果你和老周一樣,小時候特別喜歡搞破壞(什么電器都敢拆),那下面這樣小喇叭你一定見過。
這種喇叭其實以前很多錄音機都用,包括上小學時買來做英語聽力的便攜錄音機。嗯,就是放錄音帶的那種,錄音帶也叫磁帶或卡帶,有兩個輪子,錄音機的動力轉軸會帶動輪子轉動,然后就能聽到聲音了。
小時候,放學從學校走回家,途中就能看到不少于十處賣錄音帶的,有文具店的,有蹲路邊賣的,甚至連一些賣早餐的店也賣。至于是否正版,這個你懂的。反正 1.5 元到 2 元一盒,零花錢省點用的話,一個星期能買到兩三盒,然后回到家里又可以嗨了。也不用擔心被長輩們發現,因為他們也喜歡聽,被發現了他們會和你一起分享。
玩具用的喇叭會稍微比這個小一點,有正圓形的,也有橢圓形的;老周曾經在一個電子琴里拆出有正方形的喇叭,以老周幼年的拆機經驗,方形是極罕見的,正圓形居多。
網上購買,一般會買到有焊接杜邦線的,以及無焊接線的。
有焊接杜邦線的就爽了,直接上線;至于無線的,如果你焊接技術好的話,也可以自己焊,如果沒電烙鐵沒焊錫絲也不要緊,可以用帶杜邦頭的鱷魚夾,直接夾住接線孔就行了。畢竟兩邊的線離得比較遠,兩個鱷魚夾不會碰到一起,就不必擔心短路了。
除了上面介紹的喇叭,還有一種模塊也能播放音樂,那就是蜂鳴器。
注意蜂鳴分為無源和有源,上圖中,左邊的是無源蜂鳴器,右邊的是有源蜂鳴器。
有源蜂鳴器,只要電平信號就能發聲,而且只能產生固定音高的聲音,所以,想讓它播放音樂是沒門的。從圖中你會看到,有源蜂鳴器上那塊黑色的圓柱體(像牛糞的那個)上貼著紙簽,如果不撕掉,發出的聲音刺耳但音量很小;如果把紙簽撕掉,音量變大但沒那么刺耳。我們這個讓喇叭播放音樂的實驗必須使用無源蜂鳴器,所以買的時候要看清楚是有源的還是無源的。
好了,上面介紹的是完成實驗的器件,至于是選小喇叭還是蜂鳴器,你看著辦,因為兩者原理一樣——我們物理課上學過,音高是由頻率決定的。
上一篇爛文中,老周扯了 PWM 調光的實驗,由于 PWM 能以不同的頻率輸出電平信號,所以設置不同的頻率,再發送PWM方波,就能讓喇叭發出不同音高的聲音了。喇叭不能直接上電源,那樣是不能放音樂的,只能聽見地雷爆炸的聲音。再次強調一下,是改變 PWM 的頻率,不是占空比,改變占空比只能控制聲音強度。
下面開始實驗,此次實驗老周選了一首很簡單的歌,大家都聽過的,《世上只有媽媽好》。簡譜如下:
速度是每分鐘 80 拍,所以每一拍(四分音符)的時長為 60/80 = 750 毫秒。接下來咱們確定一下曲中各音符的時值。
1、帶附點的四分音符,時值為 750 + 750/2 = 1125 ms。附點就是延長當前音符時值的一半,所以四分音符加附點就是加上半拍的時值。
2、四分音符:750ms。
3、八分音符:750 / 2 = 375ms。
4、二分音符,后面有一橫線的,就是兩拍,750 * 2= 1500 ms。
至于每個音符的頻率,可以直接網上查。
此處老周選用國際標準 A(中音 La)的頻率(440 Hz)作為中音音域的參考點,于是得到各音階的頻率。
音階頻率最終取值低音部分低音 5195.998196 Hz低音 6220.0220 Hz低音 7246.942247 Hz中音部分中音 1261.626262 Hz中音 2293.665294 Hz中音 3329.628330 Hz中音 4 349.228 349 Hz 中音 5 391.995 392 Hz 中音 6440.0440 Hz 中音 7 493.883 494 Hz 高音部分 高音 1 523.251 523 Hz
封裝一個類,名為 NotePlayer,調用 PlayNote 方法播放指定頻率的聲音,持續 X 毫秒。
class NotePlayer : IDisposable
{
private PwmChannel _pwmch = null;
// 構造函數
public NotePlayer() => _pwmch = PwmChannel.Create(0, 0);
public void Dispose()
{
_pwmch?.Dispose();
}
/// <summary>
/// 播放指定頻率的聲音
/// </summary>
/// <param name="freq">聲音頻率</param>
/// <param name="duration">持續時間(毫秒)</param>
public void PlayNote(int freq, int duration)
{
_pwmch.Frequency = freq;
_pwmch.Start(); // 開始播放
DelayHelper.DelayMillis(duration);
_pwmch.Stop(); // 停止播放
}
}
核心部分是 PlayNote 方法,首先設置頻率,然后調用 PwmChannel 的Start方法開始發送脈沖,隨后持續一段時間(這段時間就是音符的時值,請看上文),播放完后,調用 Stop方法停止脈沖,喇叭不發聲。
這里面有個輔助方法 DelayMillis,用來暫停 X 毫秒,你完全可以用 Thread.Sleep 方法,這里老周寫這個方法,用的是另一種思路——這是參考微軟的寫法。
class DelayHelper
{
public static void DelayMillis(int ms)
{
long ticks = ms * Stopwatch.Frequency / 1000;
long targetTicks = Stopwatch.GetTimestamp() + ticks;
do
{
Thread.SpinWait(1);
}
while (Stopwatch.GetTimestamp() < targetTicks);
}
}
原理是運用了 Stopwatch 類的計時器,GetTimestamp 方法總能返回計時器最新的 Tick,接著進入循環,每輪循環中調用 Thread.SpinWait(1) 只等待一個代碼周期,這個時間很短,微秒級別的。循環退出條件是 GetTimestamp 方法返回的 Tick 達到我們預定好的時間。
這種方案適合對時間精度高的等待方案,比如等待幾十微秒的。
這里要思考一件事:我們如果把每首曲子的音符都寫進代碼中,如果要播放其他曲子就得改一大遍代碼,很不靈活。當然像 Arduino 那樣沒有操作系統且內部存儲空間很小的板子,要么把代碼寫死,要么加個外部的 SD 卡模塊,把音符信息放SD卡上,然后在代碼中讀。對于樹莓派來說,這事情好辦得要命。樹莓派帶操作系統,而且自身有 micro SD 卡接口,讀寫文件相當方便。
因此,老周把《世上只有媽媽好》的音符頻率和時值輸入到一個文本文件中,要換曲子直接換個文件就完事。格式很簡單,每行一個音符,包括頻率和時值,用空格分開。于是,《世上只有媽媽好》的文件如下:
440 1125
392 375
330 750
392 750
523 750
440 375
392 375
440 1500
0 750
330 750
392 375
440 375
392 750
330 375
294 375
262 375
220 375
392 375
330 375
294 1500
0 750
294 1125
330 375
392 750
392 375
440 375
330 1125
294 375
262 1500
0 750
392 1125
330 375
294 375
262 375
220 375
262 375
196 1500
0 750
其中,你會看到有幾行,音符頻率是 0,這個是為了讓喇叭有停頓。
再寫一個 MusicPlayer 類,可以控制播放整首曲子,并可以指定循環次數。
public class MusicPlayer : IDisposable
{
private bool _playing = false; // 表示是否正在播放
NotePlayer _noteplayer = null;
Stream _stream = null;// 文件流
#region 構造函數
public MusicPlayer(string noteFilepath)
{
_noteplayer = new NotePlayer();
_stream = File.OpenRead(noteFilepath);
}
#endregion
/// <summary>
/// 播放音樂
/// </summary>
/// <param name="count">重復次數,-1表示無限循環</param>
public void Start(int count = 1)
{
_playing = true;
if(count == -1) // 無限循環
{
while(_playing)
{
PlaySong();
}
}
else
{
while (_playing && count > 0)
{
PlaySong();
count--;
}
}
}
/// <summary>
/// 停止播放
/// </summary>
public void Stop() => _playing = false;
public void Dispose()
{
_stream?.Close();
_stream?.Dispose();
_noteplayer?.Dispose();
}
#region 私有方法
private void PlaySong()
{
string line = null;
_stream.Seek(0L, SeekOrigin.Begin);
// 這里一定要讓 leaveOpen 參數為 true
// 不然 reader 關閉時會直接把文件給釋放
// 后面就不能播放第二遍了
using StreamReader _noteReader = new(_stream, leaveOpen: true);
line = _noteReader.ReadLine();
int freq, dura;
while (_playing && (line is not null))
{
string[] _s = line.Split(' ');
if (!int.TryParse(_s[0].Trim(), out freq))
{
continue;
}
if (!int.TryParse(_s[1].Trim(), out dura))
{
continue;
}
if (freq < 0 || dura < 0)
{
continue;
}
// 播放音符
_noteplayer.PlayNote(freq, dura);
// 播放完讀下一個音符
line = _noteReader.ReadLine();
}
}
#endregion
}
打開包含音符頻率和時值的文件,一行一行地讀。每讀出一行,以空格作分隔符拆開字符串——可拆成兩個元素的字符串數組。第一個元素為頻率,第二個元素為時值,隨后用前面封裝的 PlayNote 播放。
注意實例化 StreamReader 時,一定要保證它被釋放時不要關閉文件,不然打開文件后只能播放一次了,后續的重復播放就會報錯。
回到程序的 Main 方法。
class Program
{
// 聲明字段
static MusicPlayer ply = null;
static void Main(string[] args)
{
// 當按取消鍵時清理資源
Console.CancelKeyPress += (_,_) =>
{
ply?.Stop();
ply?.Dispose();
};
ply = new("./test01.txt");
// 嘗試通過命令行參數獲取播放次數
int count = -1;
if(args is { Length: > 0})
{
string s = args[0];
if(!int.TryParse(s,out count))
{
count = -1;
}
}
Console.WriteLine($"播放{count}次……");
ply.Start(count);
ply.Dispose();
}
}
這里還實現了通過命令行參數來設定循環播放次數,-1為單曲循環。
最后是發布,上傳到樹莓派。
下面看怎么接線。
一、如果用小喇叭,注意正負極。如下圖,左邊是負極(接線孔右側有“-”),右邊是正極(接線孔左側有“+”)。負極接樹莓派的 GND(有多個,隨便挑一個),正極串聯一個大于 100 Ω 的電阻(電阻一定要接,不然會有破音,而且時間長了會燒掉喇叭,阻值 100 - 200 均可,電阻大了聲音小一點)后接 GPIO 18,這個你看過上一篇文章就知道了,4B 只有這個引腳能產生第一路 PWM,其他樹莓派你可以自己試。
二、使用無源蜂鳴器。這個得看你買的模塊是什么樣子的,老周買的這個是三個引腳的。
VCC 接樹莓派供電腳,3.3V 和 5V 均可,都兼容,放心燒不了,上面有100歐的電阻。
GND 接樹莓派 GND。
IO 接樹莓派的 GPIO 18。
執行程序,就可以欣賞音樂了。
示例源代碼,請點擊這里
可以試聽一下效果
=====================================================================
補充一下,開發板只能產生方波,不能產生正弦(含余弦)波,更不能產生疊加的交流聲波。所以,它只能依據頻率來產生不同的音高,你不能控制其音色,更別指望變成自制 Midi。樹莓派主板上是有 3.5 mm 音頻接口的,要看電影要聽歌,跟電腦一樣,插個耳機或有源音箱(如低音炮)即可。也可以去買一塊專門的功放模塊(針對像 Arduino 那樣沒有音頻接口的板子),不用寫代碼驅動,插上音響就能嗨。當然也有藍牙功放模塊,網購無極限,啥都有可能買到。所以這年頭想DIY還是比較容易的。
原文地址:https://www.cnblogs.com/tcjiaan/p/14395271.html
文首發于『阿里云 IoT 開發者社區』,更多精彩物聯網內容歡迎前往瀏覽。
智能家居可謂是今年物聯網的熱門領域,通過智能單品和智能音箱,人們已然把『智能』兩個字變成了生活的理所應當。搭建云上之家除了買買買,還能 DIY。依托阿里云物聯網平臺,我們用 30 行代碼來搞定一套智能家居解決方案。
常見的智能家居解決方案包括了設備端、上云、應用端三大部分,更廣的還涉及大數據及人工智能。傳統的物聯網開發非常強調流程性,即設備端、云、應用端三個步驟需要依次進行。而今天,依托于阿里云物聯網平臺的『物模型』基礎,物聯網開發的兩端可以齊頭并進,節省大量的人力物力成本。
齊頭并進顯然很誘人,但是能否再更進一步,一人 Handle 全部開發呢?答案是 YES!
目前,有大量互聯網開發者由于缺乏嵌入式開發能力,如C/C++語言基礎,止步于物聯網藍海的大門。通過阿里云 IoT 提供的 TinyEngine 引擎,可以快速使用 Javascript 進行設備端開發,完美解決這部分開發者的心頭大患。而針對不熟悉前后端開發的嵌入式開發者,阿里云物聯網平臺一樣提供了『可視化搭建應用』等快速上手的功能,零代碼實現應用開發,大大減輕學習負擔。
下面我們就使用阿里云物聯網開發平臺的 TinyEngine 引擎和可視化搭建功能,30 行代碼快速開發一個由燈和溫濕度計組成的智能家居系統。
首先,申請阿里云賬號,并開通登陸 Link Develop 一站式開發平臺:https://linkdevelop.aliyun.com。
之后,新建項目(項目名任意)—— 設備開發 —— 新增產品 —— 所屬分類按需選擇『燈』或『溫濕度計』,通訊方式選擇 WiFi ,數據格式選擇Alink —— 完成。
完成后選擇『設備開發』標簽頁 —— 新增調試設備,記錄下設備三元組。
打開嵌入式 Javascript 在線工作臺(沒錯,開發環境都不用搭建),創建新項目。替換 index.js代碼:
1. 燈
var deviceShadow = require('deviceShadow'); var ledHandle = GPIO.open("led1"); deviceShadow.bindDevID({ productKey: "", deviceName: "", deviceSecret: "" }); function main(err){ if(err){ console.log("連接平臺失敗"); }else{ console.log("主程序開始"); deviceShadow.addDevSetPropertyNotify("LightSwitch", function (lightStatus) { GPIO.write(ledHandle, 1-lightStatus); }); var mainLoop = setInterval(function () { var ledStatus = GPIO.read(ledHandle); deviceShadow.postProperty("LightSwitch", 1-ledStatus); }, 2000); } } deviceShadow.start(main);
2. 溫濕度計
var deviceShadow = require('deviceShadow'); var shtc1 = require('shtc1'); var handle = new shtc1('shtc1'); var ledHandle = GPIO.open("led"); deviceShadow.bindDevID({ productKey: "a17vi82MmxP", deviceName: "0001", deviceSecret: "tYUngSMqYeDxODgtX3DNKkQ7920I3t4T" }); function main(err) { if (err) { console.log("連接平臺失敗"); } else { console.log("主程序開始"); var mainLoop = setInterval(function () { var val = handle.getTempHumi(); console.log('shtc1:temp=' + val[0] + ' humi:' + val[1]); deviceShadow.postProperty("CurrentTemperature", val[0]); deviceShadow.postProperty("RelativeHumidity", val[1]); }, 2000); } } deviceShadow.start(main);
將設備連接至電腦,點擊『連接』并『運行』,設備啟動后會自動加載并運行index.js這個文件,同時上報數據至阿里云物聯網平臺。
既然是系統,沒有應用可不行,我們利用可視化搭建功能 0 代碼快速完成一個應用,只需依次拖入儀表盤和開關組件,替換圖片,綁定設備即可完成全部操作。
齊活,短短 30 行代碼搭建出的端到端智能家居系統就完成了,保存發布后就可以分享給他人訪問了。
配合的 TinyEngine 引擎和可視化搭建,開發者無需學習新的編程語言,即可無縫快速切入物聯網開發,也彰顯了阿里云物聯網平臺的包容性和獨創性。各位開發者,趕緊丟掉猶豫,上手試試吧!https://linkdevelop.aliyun.com
作者:cxlwill
在的消費市場的在營銷的時候都喜歡加上輕度兩個字,例如輕度奢華。
其實背后邏輯主要還是,高端奢侈品從火爆到下滑,間接帶動更多了更多年輕消費階層對高品質產品的追求。然而他們手上的錢又買不起高端奢侈品,所以輕度奢侈的概念就是為了契合他們而誕生了。
在電子消費領域同樣如此,例如式微已久的家庭影院產品,高端家庭影院因為價格和安裝問題沒辦法刺激年輕群體消費,同時網絡下載等渠道又滿足了很多低端用戶的需要。不過總會有一些人,希望有好一點影音設備,又沒辦法承擔高昂的產品或者有精力去重新布線裝修。我將這樣的人定義為輕度發燒玩家,因為我就是這類人。
傳統意義上,一套家庭影院多則五六千、少則幾萬幾十萬都可以,但都有一個問題是安裝時難于布線。幸好今年2.4Ghz技術發展得很好,所以無線家庭影院已經不需要上萬的價格也能買到。這正好也是我們這種人可負擔得起的區間。
使用簡介:
而今天有機會提前體驗到飛利浦這套CSS5530家庭影院,簡直就是為了我們這類年輕用戶而推出。在香港官網看到這套設備屬于ZENIT的系列,這套音響不再是傳統的黝黑的外形,而是改用灰色加上淺色實木裝飾的造型,官方稱為禪學美感,為的是更好地融合到現代年輕人的家居風格中。
飛利浦CSS5530是一套的5.1聲道的家庭影院系統,即包含了四個環繞聲道衛星音箱、一個中置音箱以及一個低音炮。在傳統的5.1聲道家庭影院中,上述幾個音箱都需要通過線材直接AV功放連接。而目前主流的無線家庭影院則實現去AV功放化,將解碼和功放集成在了中置音箱內。
正如CS5530的中置音箱,除了擔當音箱的作用還要承擔信號輸入和左右衛星音箱輸出,以及無線信號傳輸的作用,可以說是系統核心所在。這個中置音箱背部除了電源、衛星音箱的接線口以外,還有光纖、HDMI輸入/輸出各一個、以及一個USB接口。另外CSS5530的HDMI接口支持4K信號輸出,所以不用擔心你的新電視和高清播放器沒辦法兼容。
中置音箱負責左前右前兩個聲道的輸出,而后方的兩個衛星音箱則需要另外一個接線器連接,這個后置接收器大小和機頂盒接近,接上電源和音箱就可以自行配對成功。
衛星音箱底部有一個繞線柱,線纜長度有五米之長,基本滿足大多數空間的需要。接上線后,大概就是這個樣子了。
CSS5530的低音炮將一顆6.5英寸的喇叭做成下射式,并有一個擋板反射低頻,這樣能保證在不同的地板材質上都能獲得同樣的低頻擴散效果,避免放在例如地毯上會出現吸音的問題。它的背部沒有什么多余接口僅有一個電源插孔,所以只要接上電源就能用,并可以隨意擺放在屋內不同的空間。一般我們會放在墻角,或者放在沙發旁邊也行。
也就是說,要完成這套家庭影院的安裝,你只需要保證在沙發后方有一個插座,以及電視機附近有2個空余的插座就可以了。
影音體驗:
CSS5530所附贈的遙控器上布滿了按鈕,可調節的功能很多,除了切換音源,還可以調節音效模式、高頻低頻調節、夜間模式以及設置聲音延時功能等等。
飛利浦CSS5530支持多個信號源輸入,除了通過遙控器,在中置音箱的控制面板也可以切花,在音箱前方會有一組LED顯示當前輸入狀態。
安裝完畢我們來試試實際的效果,我們選了一套藍光光盤作為片源進行測試。包括《諜影重重3》《星球大戰外傳 俠盜一號》等。
測試時的聽感以機器默認狀態為準,有額外設置低頻和高頻的增益的話會另外說明。
我們之前曾經體驗過好幾款同樣使用了無線傳輸技術的飛利浦家庭影院,包括高端旗艦的Fidelio系列。
而CSS530給我的感受是——作為家庭影院的核心,CSS5530在低頻上的表現相當不錯,與高端的Fidelio系列相差甚至不會有太大的差異。即便在40平方的客廳,也能塑造不俗的氛圍感。低頻在爆炸場景或者營造氣氛情境中都非常重要。另外,在《諜影重重3》里,被封為經典的打斗鏡頭中,每一拳都需要低頻的襯托才顯得到位,這一點CS5530是能做到的。當然我個人是對過量低頻比較方案,默的低頻量我覺得剛剛夠了,如果你客廳隔音不錯,又追求更好的效果的話,可以適當把低頻增益增加1或者2級。
中置喇叭的人聲也是另一個關鍵,CSS5530的中置喇叭聲音以偏薄而亮麗的中頻為主,這樣才比較好地突出電影中的對白。
而CSS5530的環繞衛星音箱表現中規中矩,他能很好地做好環繞聲以及背景聲播放的職責。
另外,CS5530支持藍牙、USB等功能,我們用一臺支持APTX的手機連接CSS5530的藍牙,播放音樂時,CSS5530會變成一個2.1的音響套裝。整體上CSS5530的音質讓人驚喜,他的中頻非常寬松,但又有一定的線條感,聽交響樂時,管弦樂聲部的分離是不會擁擠在一塊的。而聽流行樂又有6.5寸低音炮能夠滿足歌曲節奏的需求。
值得一提的是,如果你家客廳足夠大,那么也可以嘗試按下遙控器上的Sound按鍵開啟Party模式,該模式下,所有喇叭都會以立體聲工作,等于提高了整個空間的聆聽體驗,保證在個個角落都同樣能聽到高品質的立體聲音樂。
另外,如果你所看的電影或者玩的游戲只支持立體聲輸出,那么也可以通過開啟Movie模式開啟CSS530所內置的Dolby Pro Logic II功能,將立體聲音源強化為5.1聲道輸出。
小結:
飛利浦CSS5530的表現實在讓人驚喜,畢竟它的官方售價一點都不昂貴,但實際體驗中給我帶來的感受卻可直逼旗艦Fidelio系列。
而它和旗艦之間的差距,更多地體現在功能上例如不支持隨需環繞技術和輸入接口的減少,以及易用性方面。這也是CSS5530唯一的一個小缺點——后置環繞音響仍然需要一個比較平穩的擺放空間。畢竟衛星音箱體積不算小,我建議還是最好買一個小型的支架來擺放它,才能享受最好的環繞聲效果。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。