當你說不行時,你應該說些什麼:以Android播放midi為例

來源:互聯網
上載者:User

當你說不行時,你應該說些什麼:以Android播放midi為例

中國好幾年前都對能對美國說"不",軟體工程師也經常要對使用者和同事說"不"。
但是別人經常還要在你說不以後繼續喋喋不休,為什麼呢?

據說男生說不的時候,就是不的意思;據說女生說不的時候,是請再繼續表現的
意思。這坑害了很多猥瑣男。因為,只有她希望你繼續表現的時候,那時"不"的
意思才是請繼續表現,否則,"不"的意思就是"不"。一些女生假設對方能夠理解
這一顯然的事實:即,你是否是被歡迎繼續表現的。

而這個世界上沒有顯然的事情。繼續表現的,多是猥瑣男,被希望繼續表現的,
通常很快就引退了。

關於如何說是,咱們今天不討論;今天單討論一下如何明確地說不。

會發生上述誤會,蓋因東方民族隱晦含蓄的表達方式傳統。看過一個日本片子。
某個提了個什麼主意,女主角坐在那裡,低頭著頭,很堅毅地說:"雖說很好。"

你不要以為還有下文,她說到這裡就戛然而止了。日本人就是這樣說話的。她發
出的聲音是"雖說很好",但實際想傳達的是後面所有沒說的內容。

在工程中,使用者和同事也經常會誤解。那麼如何準確地傳達"不"的資訊呢?

1. 對使用者

這個簡單。

除了告訴他不以外,還要告訴他 技術上完全可以,但是...然後開始羅列代價:
時間(工期)、經費等等。

然後他就自動引退了。這在女生說不的情境中,類似於,女生說完不以後,再補
充,"其實呢,也不是不行,但是需要加些條件。我想要的很簡單:一座大大的
露台,上面有個鞦韆……"

明確的回絕,就是 不行 + 你不具備"行"的理由。

2. 對同事

明確告訴同事,尤其是分配給你任務的那個人,"你的想法很豬頭" 的方法是,
告訴他,他的想法不可行的原因。

並且,為了交流簡潔起見,把他所有可能的提問,所有可能修正的主意都羅列出
來,然後一一否定。寫文檔或報告的時候,不要期待互動,不要期待他問你答,
用答案堵住他所有可能下嘴的地方。

不恃敵所不攻也,恃吾有以待也。

以下是一個執行個體故事。這也我們為什麼要訓練寫實驗報告的原因,它記錄了過程
和資料,以此支援你的看法。沒有人會像科幻電影裡的總統啥的那樣,因為你瓊
瑤般喊"你們相信我吧,地球真的要毀滅啦"就相信你。

我們應該做的是:告訴小夥不行,然後對他淡定地笑笑,然後準確清晰完整地說
出他不行的原因。

背景:

我請牛同學做Android下的一個程式原理,播放音樂合弦,比如大三度。意思是,同
時把do,re,mi的聲音發出來。

技術方案之一是用PCM混音,之二是在MIDI中同時播放這幾個音。牛同學分別試
了。

牛同學試了一段時間以後,說終於找到一個產生midi檔案的方法。

我提出新的要求,不要把midi檔案寫到檔案系統(internal storage)中,而是
用java的stream,在記憶體(RAM)中直接發給MediaPlayer播放。

牛同學說:不行。

故事開始了。

你說不行,我當然不能因為是你說的,然後就信了。要有事實。

所以牛同學發來他的代碼,我學習了一段,發現真的不行。然後寫了下面這封信。
略有修改。

----信的本文由此開始----

下面提到的"應該"是指 建議給你的 報告的寫法.有了這些你"應該"提供的資料,我才能瞭解你研究了哪些必要的方法.
這是用以證明你研究的路線是正確的方法.
或者換種說法,如果以下報告中的"應該"部分你已經告訴我,我就不必看你的代碼了.

1. 你應該提供我MidiFile的出處,以便我參考,因為MidiFile不是你寫的,且不是java/android的一部分;

2. 你是否參考了此郵件後面網址的實現?[http://kevinboone.net/javamidi.html]

3. 我提到的不必向檔案系統中寫出midi檔案,
原計劃的路線是這樣的:
通過重寫 writeToFile 實現,把這個方法中的寫到檔案系統中轉為對Stream賦值,也可以把midi的內容放在 vector<byte>中;

4. 然後設定MediaPlayer.SetDataSource()的參數為這個vector或者Stream.

下面是我尋找解決方案的路線。

4.1 MediaPlayer需要FileDescriptor

[http://developer.android.com/reference/android/media/MediaPlayer.html#pubmethods]
MediaPlayer.setDataSource(FileDescriptor fd)
Sets the data source (FileDescriptor) to use.

4.2 FileDescriptor可以由FileInputStream/FileOutputStream建立

[http://developer.android.com/reference/java/io/FileDescriptor.html]
It's possible to get the file descriptor used by some classes (such as
FileInputStream, FileOutputStream, and RandomAccessFile), and then
create new streams that point to the same file descriptor.

[http://developer.android.com/reference/java/io/FileOutputStream.html]
FileInputStream.getFD()
public final FileDescriptor getFD ()
Returns the underlying file descriptor.

4.4 到這裡,我的思路走不下去了。因為FileInputStream的建構函式要求儲存在FLASH中的檔案。

你應該列出以下方法,並說明MediaPlayer沒有其他的方法 setDataSource.

void setDataSource(String path)
Sets the data source (file-path or http/rtsp URL) to use.
void setDataSource(FileDescriptor fd, long offset, long length)
Sets the data source (FileDescriptor) to use.
void setDataSource(FileDescriptor fd)
Sets the data source (FileDescriptor) to use.
void setDataSource(Context context, Uri uri, Map<String, String> headers)
Sets the data source as a content Uri.
void setDataSource(Context context, Uri uri)
Sets the data source as a content Uri.

4.5 然後我開始查是否有其他的辦法。因為利用stream而不通過檔案系統,這實
在應該是個非常通用的方案,android sdk沒有理由不支援啊。

[http://developer.android.com/reference/android/content/Context.html#getCacheDir()]討論了這一問題,
播放記憶體中,而不是flash(internal storage)中的midi檔案。

4.6 下面這個方法我同意[http://code.google.com/p/android/issues/detail?id=739]

: Comment 7 by steveold...@gmail.com, Aug 19, 2008
: From the ReadMe included with 0.9 SDK.

: Unfortunately, the ability to play audio streams from memory (such as via an 
: InputStream or Reader) will not be possible in Android 1.0.  As a workaround, we 
: recommend that developers save media content to SD card and use MediaPlayer to play 
: from a file URI, or embed a small HTTP server and play from a URI on localhost (such 
: as http://127.0.0.1:4242/something 

楊註:但是第二天一早,我又意識到這是不行的。因為讀http必然要求那個midi
檔案已經存在了。這與我原計劃不希望寫入檔案系統相違背。

同一貼子有人提到

: Comment 12 by seeingwi...@gmail.com, May 19, 2009
: Issue now resolved with AudioTrack in Android 1.5 (Cupcake)

這是我們以前提到過的方法,在[http://developer.android.com/reference/android/media/AudioTrack.html] 裡提到,
不過需要PCM作為buffer而不能用midi作為buffer.

正如同一貼子的人回答道:

: Comment 22 by sam.clegg, Sep 13, 2011
: Is there really still no streaming audio support in android?

: AudioTrack doesn't help as it only works for PCM samples, not encoded files.

4.7 至此,我提出的從stream中寫入midi,然後從stream中構造MediaPlayer,這一方案可以得出結論 不行.

我們不能因為誰說不行就認定不行,而只能根據以上的分析.

4.8 我們仍然可以用PCM的方法合成和弦.我建議還是試回這個方法.

楊註:然後第二天一早,我又反悔了,因為PCM的尺寸會比MIDI大很多,這不是我
們希望的。

請用MATLAB做這樣的實驗:

楊註:所以下面的實驗我就在此省略了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.