天天看點

Android 錄音PCM 轉G711U,非常簡單,非FFMPEG

        最近在開發對講機時,由于G711資料壓縮的比較好,适合網絡傳輸,是以音頻采用  了 G711編碼。但是Android裡面的AudioRecord編碼出來的是 PCM資料,是以要對資料進行編碼後再發送。實作對講功能。

部落客已經測試代碼是可行的。而且非常簡單,不需要ffmpeg。PCM 轉 G711資料長度要減少一半。代碼非常簡單,不要去編譯ffmpeg(部落客還沒編譯通過呢)注意...我要上代碼了。都是代碼也沒啥好注釋的。

下面是代碼:

JNIEXPORT jint JNICALL Java_com_example_testjni_Hunter_PCM2G711(JNIEnv *env,
		jclass obj,jbyteArray _src) {
jsize bufsize = env->GetArrayLength(_src);
	unsigned short* src = (short*)env->GetByteArrayElements(_src, 0); 
	unsigned short* dst = (unsigned short*)malloc(sizeof(unsigned short) * (bufsize/2));
	unsigned short i;
	short data;
	unsigned short isNegative;
	short nOut;
	short lowByte = 1;
	// -----------------  encoder -------------------------
	for (i = 0; i < bufsize / 2; i++) {
			data = *(src + i);
			data >>= 2;
			isNegative = (data < 0 ? 1 : 0);
			if (isNegative)
				data = -data;
			if (data <= 1) {
				nOut = (char) data;
			} else if (data <= 31) {
				nOut = ((data - 1) >> 1) + 1;
			} else if (data <= 95) {
				nOut = ((data - 31) >> 2) + 16;
			} else if (data <= 223) {
				nOut = ((data - 95) >> 3) + 32;
			} else if (data <= 479) {
				nOut = ((data - 223) >> 4) + 48;
			} else if (data <= 991) {
				nOut = ((data - 479) >> 5) + 64;
			} else if (data <= 2015) {
				nOut = ((data - 991) >> 6) + 80;
			} else if (data <= 4063) {
				nOut = ((data - 2015) >> 7) + 96;
			} else if (data <= 7903) {
				nOut = ((data - 4063) >> 8) + 112;
			} else {
				nOut = 127;
			}
			if (isNegative) {
				nOut = 127 - nOut;
			} else {
				nOut = 255 - nOut;
			}
			if (lowByte)
				*(dst + (i >> 1)) = (nOut & 0x00FF);
			else
				*(dst + (i >> 1)) |= ((nOut << 8) & 0xFF00);
			lowByte ^= 0x1;
		}
	
	//----------------------------encode  end -------------------------------
	unsigned char* pdata = (char*)(&(dst[0]));
	
	// 得到的pdata 就是 g711資料。可以轉成byte[] 數組,然後發送,或者播放。
	
	return 0;
}
           

        這段代碼已經用到了  真實的項目中了。       pcm的資料是在   16位,雙通道,8000比特上錄的。

上面的代碼隻需要在      

AudioRecord.read 之後得到的 byte[] 數組,傳進來編碼一下就行了!!!!!!!!!!簡單吧。