Cochlear Impant: Periodic Service

This article discuss a periodic real-time service implementation (ProcessingService) that uses a periodic task within a real-time service to express a periodic task. Fig.1 shows the static declaration of ProcessingService in RTDroid application manifest, and its related communication channels. Fig.2 lists its corresponding implementation.

<service android:name="rtdroid.ci.ProcessingService">
  <rtdroid:priority scheduler="FIFO" priority="89"/>
  <rtdroid:scopeSizes total="81M" persistent="60M" release="1M"/> 
  <rtdroid:periodic>      
    <period ms="8" ns="0"/>
    <startTime relative="true" ms="65" ns="0"/>
    <rtdroid:subScopeSize release="20M" />
   <rtdroid:priority scheduler="FIFO" priority="80"/>
  </rtdroid:periodic>
  <intent-filter rtdroid:realtime="true" rtdroid:concurrentCount="4"  
            rtdroid:role="subscriber">   
    <action android:name="msg.buf.handler"/>           
  </intent-filter>
  <intent-filter rtdroid:realtime="true" rtdroid:concurrentCount="2" 
            rtdroid:role="publisher">     
    <action android:name="audio.output"/>         
  </intent-filter> 
</service>
...
<rtdroid:channel name="msg.buf.handler" type="rt_handler">              
  <data rtdroid:size="1792B" android:mimeType="application/rtdroid.int" />
</rtdroid:channel>
<rtdroid:channel name="audio.output" type="broadcast_intent">
  <data rtdroid:size="400B" android:mimeType="application/octet-stream" />
</rtdroid:channel>
Fig.2 Real-Time Audio Processing Service Declaration
 1 public class ProcessingService extends RealtimeService implements Repeatable{
 2   public static final int MESSAGE_AUDIO_SAMPLE = 1;
 3   public static final int MESSAGE_CONFIG_CHANGE = 2;
 4   public static final int NUM_CHANNELS = 22;
 5   private static final int windowSize = 128;
 6   private static final int bufSize =  1792;
 7 
 8   private int volume;
 9   private double window[];
10   private int[] buffer;
11   private FFT fftClass = new FFT(128);
12   private MessageBufferHandler handler;
13   private Object lock = new Object();
14 
15   @Override
16   public void onCreate() {
17     executeInPersistent( new Runnable() {
18       @Override
19       public void run(){
20         volume = 40;
21         window[] = new double[windowSize];
22         for(int n=0;n<windowSize; n++) {
23             window[n] = 0.49656*Math.cos((2*Math.PI*n) / (windowSize - 1))
24               + 0.076849 * Math.cos((4 * Math.PI * n) / (windowSize - 1));
25         }
26         fftClass = new FFT(128);         
27         handler = new MessageBufferHandler("msg.buf.handler");;
28         lock = new Object();
29       } 
30     }); 
31   }
32     
33   @Override
34   public int onStartCommand(Intent i, int f, int id) {
35       registerRealtimeHandler("msg.buf.handler", handler);
36       registerPeriodicTask("processTask", processTask);
37   }
38   ...
39   @Override
40   public void onDestroy() {
41     stopPeriodicTask("processTask");
42     unregisterRealtimeHandler("msg.buf.handler");
43   }
44     
45   @Override
46   public void onRelease(Context context) {
47     if ( buf is ready ) { 
48     //check configuration
49     //apply volume
50     //audio signal processing
51     //send intent to OutputReceiver
52     }
53   }
54 }
Fig.2 Simplified Real-Time Audio Processing Service