summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/android/pcm-android.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-02 20:34:47 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-02 20:34:47 +0000
commit240923a801382c86545d10be167a15892a556fb6 (patch)
tree3c0e07ec3abf0c493a0b24b0b57e8bbd0200f7f6 /firmware/target/hosted/android/pcm-android.c
parent850efead04f10488b478a0f255a2464a01156a7f (diff)
downloadrockbox-240923a801382c86545d10be167a15892a556fb6.tar.gz
rockbox-240923a801382c86545d10be167a15892a556fb6.zip
Rockbox as an application: Commit current Android port progress.
General state is: Rockbox is usable (plays music, saves configuration, touchscreen works too). Problems: - Playing music in the background (i.e. when switching to another app) doesn't work reliably, but I'm working on that now. - no cabbiev2 (only some preliminary files for it), no other default theme. - screen flickers sometimes if the updates are too frequent - no multi screen apk/package - strange behavior when a phone call comes in The java files (and the eclipse project) resides in android/, which is also supposed to be the build folder. I've put a small README in there for instructions. There are some steps needed after the make part, which are described there, and which eclipse mostly handles. But there ought to be some script/makefile rules which do that instead in the future. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27668 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/hosted/android/pcm-android.c')
-rw-r--r--firmware/target/hosted/android/pcm-android.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/firmware/target/hosted/android/pcm-android.c b/firmware/target/hosted/android/pcm-android.c
new file mode 100644
index 0000000000..91978f422b
--- /dev/null
+++ b/firmware/target/hosted/android/pcm-android.c
@@ -0,0 +1,174 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2010 Thomas Martitz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <jni.h>
23#include <stdbool.h>
24#include <system.h>
25#include "pcm.h"
26
27extern JNIEnv *env_ptr;
28extern jclass RockboxActivity_class;
29extern jobject RockboxActivity_instance;
30
31/* infos about our pcm chunks */
32static size_t pcm_data_size;
33static char *pcm_data_start;
34
35/* cache frequently called methods */
36static jmethodID play_pause_method;
37static jmethodID stop_method;
38static jmethodID set_volume_method;
39static jclass RockboxPCM_class;
40static jobject RockboxPCM_instance;
41
42
43/*
44 * transfer our raw data into a java array
45 *
46 * a bit of a monster functions, but it should cover all cases to overcome
47 * the issue that the chunk size of the java layer and our pcm chunks are
48 * differently sized
49 *
50 * afterall, it only copies the raw pcm data from pcm_data_start to
51 * the passed byte[]-array
52 *
53 * it is called from the PositionMarker callback of AudioTrack
54 **/
55JNIEXPORT void JNICALL
56Java_org_rockbox_RockboxPCM_pcmSamplesToByteArray(JNIEnv *env,
57 jobject this,
58 jbyteArray arr)
59{
60 (void)this;
61 size_t len;
62 size_t array_size = (*env)->GetArrayLength(env, arr);
63 if (array_size > pcm_data_size)
64 len = pcm_data_size;
65 else
66 len = array_size;
67
68 (*env)->SetByteArrayRegion(env, arr, 0, len, pcm_data_start);
69
70 if (array_size > pcm_data_size)
71 { /* didn't have enough data for the array ? */
72 size_t remaining = array_size - pcm_data_size;
73 size_t offset = len;
74 retry:
75 pcm_play_get_more_callback((void**)&pcm_data_start, &pcm_data_size);
76 if (pcm_data_size == 0)
77 return;
78 if (remaining > pcm_data_size)
79 { /* got too little data, get more ... */
80 (*env)->SetByteArrayRegion(env, arr, offset, pcm_data_size, pcm_data_start);
81 /* advance in the java array by the amount we copied */
82 offset += pcm_data_size;
83 /* we copied at least a bit */
84 remaining -= pcm_data_size;
85 /* let's get another buch of data and try again */
86 goto retry;
87 }
88 else
89 (*env)->SetByteArrayRegion(env, arr, offset, remaining, pcm_data_start);
90 len = remaining;
91 }
92 pcm_data_start += len;
93 pcm_data_size -= len;
94}
95
96void pcm_play_lock(void)
97{
98}
99
100void pcm_play_unlock(void)
101{
102}
103
104void pcm_dma_apply_settings(void)
105{
106}
107
108void pcm_play_dma_start(const void *addr, size_t size)
109{
110 pcm_data_start = (char*)addr;
111 pcm_data_size = size;
112
113 pcm_play_dma_pause(false);
114}
115
116void pcm_play_dma_stop(void)
117{
118 (*env_ptr)->CallVoidMethod(env_ptr,
119 RockboxPCM_instance,
120 stop_method);
121}
122
123void pcm_play_dma_pause(bool pause)
124{
125 (*env_ptr)->CallVoidMethod(env_ptr,
126 RockboxPCM_instance,
127 play_pause_method,
128 (int)pause);
129}
130
131size_t pcm_get_bytes_waiting(void)
132{
133 return pcm_data_size;
134}
135
136const void * pcm_play_dma_get_peak_buffer(int *count)
137{
138 uintptr_t addr = (uintptr_t)pcm_data_start;
139 *count = pcm_data_size / 4;
140 return (void *)((addr + 3) & ~3);
141}
142
143void pcm_play_dma_init(void)
144{
145 /* in order to have background music playing after leaving the activity,
146 * we need to allocate the PCM object from the Rockbox thread (the Activity
147 * runs in a separate thread because it would otherwise kill us when
148 * stopping it)
149 *
150 * Luckily we only reference the PCM object from here, so it's safe (and
151 * clean) to allocate it here
152 **/
153 JNIEnv e = *env_ptr;
154 /* get the class and its constructor */
155 RockboxPCM_class = e->FindClass(env_ptr, "org/rockbox/RockboxPCM");
156 jmethodID constructor = e->GetMethodID(env_ptr, RockboxPCM_class, "<init>", "()V");
157 /* instance = new RockboxPCM() */
158 RockboxPCM_instance = e->NewObject(env_ptr, RockboxPCM_class, constructor);
159 /* cache needed methods */
160 play_pause_method = e->GetMethodID(env_ptr, RockboxPCM_class, "play_pause", "(Z)V");
161 set_volume_method = e->GetMethodID(env_ptr, RockboxPCM_class, "set_volume", "(I)V");
162 stop_method = e->GetMethodID(env_ptr, RockboxPCM_class, "stop", "()V");
163 /* get initial pcm data, if any */
164 pcm_play_get_more_callback((void*)&pcm_data_start, &pcm_data_size);
165}
166
167void pcm_postinit(void)
168{
169}
170
171void pcm_set_mixer_volume(int volume)
172{
173 (*env_ptr)->CallVoidMethod(env_ptr, RockboxPCM_instance, set_volume_method, volume);
174}