您的位置:首页 > 编程语言

FM Radio项目原创代码

2013-10-18 16:45 162 查看
转载自 http://blog.csdn.net/zyw123/article/details/6891063
最近在做基于一款芯片的FM Radio.有了底层驱动,需要我做上层java代码,已经自己写jni调用驱动,实现FM Radio 的功能。

android NDK开发就不介绍了,这样的可以有很多参考。我只是把我写的部分代码拿出来与大家分享。有做FM Radio 的请参考,也可以提出意见。

首先要有功能代码:做了一个类

package com.mycompanyname.fm;

import android.util.Log;

public class FMFunction {

private static final String TAG = "FMFunction";

public FMFunction() {

Log.i(TAG,"FMFunction created......");

}

public void openFm () {

nativeOpenFM();

}

public void closeFm () {

nativeCloseFM();

}

public int[] scanChannel() {

return nativeScanChannel();

}

public void playChannel(int freq) {

nativePlayChannel(freq);

}

public int getAudioVolume() {

return nativeGetAudioVolume();

}

public void audioUp() {

nativeAudioUp();

}

public void audioDown() {

nativeAudioDown();

}

public void setMute() {

nativeSetMute();

}

public int getRssiLevel() {

return nativeGetRssiLevel();

}

//native function

private native void nativeOpenFM();

private native void nativeCloseFM();

private native int [] nativeScanChannel();

private native void nativePlayChannel(int freq);

private native void nativeAudioUp();

private native void nativeAudioDown();

private native int nativeGetAudioVolume();

private native void nativeSetMute();

private native int nativeGetRssiLevel();

static {

Log.i(TAG,"loadLibrary carry out..............");

System.loadLibrary("fmfunction-jni");

}

}

这个类介绍了要用到的radio 功能。

openFm ():打开radio

closeFm ():关闭radio

scanChannel():扫描所有频道

playChannel(int freq):播放指定频率的频道

getAudioVolume():取得当前音量值

audioUp():提高音量

audioDown():降低音量

setMute():静音

getRssiLevel():取得信号强度

只是简单的写了这些功能,这些功能对播放应该就可以了。

下面还要就这些上层功能做jni实现,jni调用驱动实现上述功能。

jni 代码如下:

#include <string.h>

#include <jni.h>

#include <stdio.h>

#include <stdlib.h>

#include <fcntl.h>

#include <malloc.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <sys/ioctl.h>

#include <linux/videodev2.h>

#include <android/log.h>

#define VIDIOC_S_HW_FREQ_SEEK 0x40305652

struct v4l2_hw_freq_seek {

__u32 tuner;

enum v4l2_tuner_type type;

__u32 seek_upward;

__u32 wrap_around;

__u32 reserved[8];

};

/* parameters for driver use */

static int fd;

int ret;

struct v4l2_capability cap;

struct v4l2_tuner tuner;

struct v4l2_audio a;

struct v4l2_frequency f;

struct v4l2_queryctrl q;

struct v4l2_control c;

struct v4l2_hw_freq_seek seek;

unsigned int i;

unsigned int mute=0;

unsigned int volume = 0;

unsigned int freq = 87500000;

void Java_com_innofidei_fm_FMFunction_nativeOpenFM(JNIEnv* env,jobject thiz) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","nativeOpenFM init............");

fd = open("/dev/radio0",O_RDONLY);

if (fd < 0) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativeOpenFM init failed : %d ",fd);

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativeOpenFM init success");

}

}

void Java_com_innofidei_fm_FMFunction_nativeCloseFM(JNIEnv* env,jobject thiz) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","nativeCloseFM .............");

close(fd);

return;

}

jintArray Java_com_innofidei_fm_FMFunction_nativeScanChannel(JNIEnv* env,jobject thiz) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","nativeScanChannel..... .......");

jintArray result;

result = (*env)->NewIntArray(env, 20);

if (result == NULL) {

return NULL;

}

/*init original array for recording frequency info */

jint num[20];

jint i = 0;

for (;i<20;i++) {

num[i] = 0;

}

/* set lowest frequency */

f.frequency = freq *2 /125;

f.type = V4L2_TUNER_RADIO;

f.tuner = 0;

ret = ioctl(fd,VIDIOC_S_FREQUENCY,&f);

if (ret < 0) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","search frequency failed");

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","search frequency success");

}

/*search channel,obtain frequency to enter array */

jint j = 0;

for (;j<20;j++) {

seek.wrap_around = 1;

seek.seek_upward = 0;

seek.tuner = 0;

ret = ioctl(fd,VIDIOC_S_HW_FREQ_SEEK,&seek);

if (ret == 0) {

f.tuner = 0;

ret = ioctl(fd,VIDIOC_G_FREQUENCY,&f);

if (ret < 0) {

__android_log_print(ANDROID_LOG_INFO,"JNIGetFrequency","get frequency failed");

break;

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","get freq is %d",f.frequency);

num[j] = f.frequency;

}

} else {

break;

}

}

(*env)->SetIntArrayRegion(env,result, 0, 20, num);

return result;

}

void Java_com_innofidei_fm_FMFunction_nativePlayChannel(JNIEnv* env,jobject thiz,jint freq){

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativePlayChannel init......,freq is: %d",freq);

f.frequency = freq;

f.type = V4L2_TUNER_RADIO;

f.tuner = 0;

ret = ioctl(fd,VIDIOC_S_FREQUENCY,&f);

if (ret < 0) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","nativePlay set frequency failed");

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativePlay carry out success");

}

/*unmute */

mute = 0;

c.id = V4L2_CID_AUDIO_MUTE;

c.value = mute;

ret = ioctl(fd,VIDIOC_S_CTRL,&c);

if (ret < 0) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativePlay can not unmute");

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativePlay unmute success ");

}

/*obtain current volume*/

c.id = V4L2_CID_AUDIO_VOLUME;

ret = ioctl(fd,VIDIOC_G_CTRL,&c);

if (ret < 0) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","get ctrl failed");

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","current volume is : %d",c.value);

}

}

void Java_com_innofidei_fm_FMFunction_nativeAudioUp(JNIEnv* env,jobject thiz) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","nativeAudioUp...............");

c.id = V4L2_CID_AUDIO_VOLUME;

ret = ioctl(fd,VIDIOC_G_CTRL,&c);

if (ret < 0) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","get ctrl failed");

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","current volume is : %d",c.value);

volume = c.value;

}

c.id = V4L2_CID_AUDIO_VOLUME;

if (volume < 15) {

c.value = ++volume;

}

volume %=0x0f;

ret = ioctl(fd,VIDIOC_S_CTRL,&c);

if (ret < 0) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","set volume ctrl failed");

}

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","after up, volume: %d",volume);

return;

}

void Java_com_innofidei_fm_FMFunction_nativeAudioDown(JNIEnv* env,jobject thiz) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","nativeAudioDown.............");

c.id = V4L2_CID_AUDIO_VOLUME;

ret = ioctl(fd,VIDIOC_G_CTRL,&c);

if (ret < 0) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","get ctrl failed");

} else {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","current volume is : %d",c.value);

volume = c.value;

}

c.id = V4L2_CID_AUDIO_VOLUME;

if (volume > 0) {

c.value = --volume;

}

volume %=0x0f;

ret = ioctl(fd,VIDIOC_S_CTRL,&c);

if (ret < 0) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","set volume ctrl failed");

}

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","after down, volume: %d",volume);

return;

}

void Java_com_innofidei_fm_FMFunction_nativeSetMute(JNIEnv* env,jobject thiz) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativeSetMute init..................mute value is : %d",mute);

if (mute == 0) {

mute = 1;

} else {

mute = 0;

}

c.id = V4L2_CID_AUDIO_MUTE;

c.value = mute;

ret = ioctl(fd,VIDIOC_S_CTRL,&c);

if (ret < 0) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","set mute ctrl failed");

}

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","set mute ctrl success");

return;

}

jint Java_com_innofidei_fm_FMFunction_nativeGetAudioVolume(JNIEnv* env,jobject thiz) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativeGetAudioVolume............");

c.id = V4L2_CID_AUDIO_VOLUME;

ret = ioctl(fd,VIDIOC_G_CTRL,&c);

if (ret < 0) {

__android_log_write(ANDROID_LOG_INFO,"JNIMsg","get ctrl failed");

return ret;

}

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","volume is %d",c.value);

return c.value;

}

jint Java_com_innofidei_fm_FMFunction_nativeGetRssiLevel(JNIEnv* env,jobject thiz) {

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","nativeGetRssiLevel init................................");

tuner.index = 0;

ret = ioctl(fd,VIDIOC_G_TUNER,&tuner);

__android_log_print(ANDROID_LOG_INFO,"JNIMsg","rssi level is %d",tuner.signal);

return tuner.signal;

}

这个jni代码可以帮助你理解驱动,以及jni的写法,其中引人#include <android/log.h>头文件是为了用logcat查看代码流程用的。

因为网上的原创代码很少,所以将这些个人原创代码提供给android开发的朋友,为大家做参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: