summaryrefslogtreecommitdiffstats
path: root/audio-ril-interface/audio-ril-interface.cpp
blob: dba1832d2f7797a8cf725d6833f0977edb3240f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**
 * Audio RIL Interface for GTA04
 *
 * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
 *
 * Audio RIL Interface is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Audio RIL Interface is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Audio RIL Interface.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <stdlib.h>

#define LOG_TAG "AudioRILInterface"
#include <cutils/log.h>
#include <media/AudioSystem.h>
#include <tinyalsa/asoundlib.h>

#include <audio_ril_interface.h>

#define DEVICE	"Goldelico GTA04"

/*
 * Structures
 */

struct gta04_pdata {
	struct pcm *voice_pcm;
	int mode;
};

/*
 * Functions
 */

void *gta04_pdata_create(void)
{
	struct gta04_pdata *pdata = NULL;

	pdata = (struct gta04_pdata *) calloc(1, sizeof(struct gta04_pdata));
	return (void *) pdata;
}

void gta04_pdata_destroy(void *pdata)
{
	if(pdata != NULL)
		free(pdata);
}

int gta04_mode(void *pdata, int mode)
{
	struct pcm_config config;
	struct gta04_pdata *gta04_pdata = NULL;
	void *buffer = NULL;
	int size = 0;

	if(pdata == NULL)
		return -1;

	gta04_pdata = (struct gta04_pdata *) pdata;

	if(mode == android::AudioSystem::MODE_IN_CALL && gta04_pdata->mode != android::AudioSystem::MODE_IN_CALL) {
		LOGD("Starting call, activating voice!");

		/*
		 * It seems that on GTA04 A4, microphone voice routing to
		 * the modem only works when a capture channel is active.
		 * Note that Android will close any existing capture channel.
		 */
		memset(&config, 0, sizeof(config));

		config.channels = 2;
		config.rate = 44100;
		config.period_size = 1056;
		config.period_count = 2;
		config.format = PCM_FORMAT_S16_LE;

		gta04_pdata->voice_pcm = pcm_open(0, 0, PCM_IN, &config);
		if(!gta04_pdata->voice_pcm || !pcm_is_ready(gta04_pdata->voice_pcm)) {
			LOGE("Failed to open capture channel!");
		}

		size = pcm_get_buffer_size(gta04_pdata->voice_pcm);
		buffer = malloc(size);

		LOGD("Reading one sample");

		pcm_read(gta04_pdata->voice_pcm, buffer, size);

		free(buffer);
	} else if(mode != android::AudioSystem::MODE_IN_CALL && gta04_pdata->mode == android::AudioSystem::MODE_IN_CALL) {
		LOGD("Ending call, deactivating voice!");

		if(gta04_pdata->voice_pcm != NULL)
			pcm_close(gta04_pdata->voice_pcm);

		gta04_pdata->voice_pcm = NULL;
	}

	gta04_pdata->mode = mode;

	return 0;
}

int gta04_mic_mute(void *pdata, int mute)
{
	return 0;
}

int gta04_voice_volume(void *pdata, float volume)
{
	return 0;
}

int gta04_routing(void *pdata, int route)
{
	return 0;
}

/*
 * Interface
 */

extern "C" {

struct audio_ril_interface gta04_interface = {
	NULL,
	gta04_mode,
	gta04_mic_mute,
	gta04_voice_volume,
	gta04_routing
};

struct audio_ril_interface *audio_ril_interface_open(void)
{
	LOGE("%s (%s)", __func__, DEVICE);

	gta04_interface.pdata = gta04_pdata_create();

	return &gta04_interface;
}

void audio_ril_interface_close(struct audio_ril_interface *interface_p)
{
	LOGE("%s (%s)", __func__, DEVICE);

	gta04_pdata_destroy(interface_p->pdata);
}

}