Browse Source

Update play-audio to 0.2

Cleanups and stream type support
android-5
Fredrik Fornwall 10 years ago
parent
commit
df22a55439
  1. 2
      packages/play-audio/build.sh
  2. 5
      packages/play-audio/play-audio.1
  3. 97
      packages/play-audio/play-audio.cpp

2
packages/play-audio/build.sh

@ -1,6 +1,6 @@
TERMUX_PKG_HOMEPAGE=http://termux.com
TERMUX_PKG_DESCRIPTION="Simple commandline audio player for Android"
TERMUX_PKG_VERSION=0.1
TERMUX_PKG_VERSION=0.2
termux_step_make_install () {
$CXX $CFLAGS $LDFLAGS \

5
packages/play-audio/play-audio.1

@ -5,13 +5,16 @@
.Nd audio player using the Android media system
.Sh SYNOPSIS
.Nm play-audio
.Op Fl s Ar stream
.Op Ar files
.Sh DESCRIPTION
The
.Nm play-audio
utility plays the files listed as arguments, in order, using the Android media system.
utility plays one or more files listed as arguments using the Android media system.
.Pp
The supported media formats may vary across difference devices and Android versions.
.Pp
The audio stream type (which affects the volume) may be specified as 'alarm', 'media' (default), 'notification', 'ring', 'system' or 'voice'.
.Sh EXAMPLES
Play two ogg files in succession:
.Pp

97
packages/play-audio/play-audio.cpp

@ -13,10 +13,21 @@ class AudioPlayer {
AudioPlayer();
~AudioPlayer();
void play(char const* uri);
/**
* This allows setting the stream type (default:SL_ANDROID_STREAM_MEDIA):
* SL_ANDROID_STREAM_ALARM - same as android.media.AudioManager.STREAM_ALARM
* SL_ANDROID_STREAM_MEDIA - same as android.media.AudioManager.STREAM_MUSIC
* SL_ANDROID_STREAM_NOTIFICATION - same as android.media.AudioManager.STREAM_NOTIFICATION
* SL_ANDROID_STREAM_RING - same as android.media.AudioManager.STREAM_RING
* SL_ANDROID_STREAM_SYSTEM - same as android.media.AudioManager.STREAM_SYSTEM
* SL_ANDROID_STREAM_VOICE - same as android.media.AudioManager.STREAM_VOICE_CALL
*/
void setStreamType(SLint32 streamType) { this->androidStreamType = streamType; }
private:
SLObjectItf mSlEngineObject{NULL};
SLEngineItf mSlEngineInterface{NULL};
SLObjectItf mSlOutputMixObject{NULL};
SLint32 androidStreamType{SL_ANDROID_STREAM_MEDIA};
};
class MutexWithCondition {
@ -53,10 +64,8 @@ AudioPlayer::AudioPlayer() {
result = (*mSlEngineObject)->GetInterface(mSlEngineObject, SL_IID_ENGINE, &mSlEngineInterface);
assert(SL_RESULT_SUCCESS == result);
SLuint32 const numWantedInterfaces = 1;
SLInterfaceID wantedInterfaces[numWantedInterfaces]{ SL_IID_ENVIRONMENTALREVERB };
SLboolean wantedInterfacesRequired[numWantedInterfaces]{ SL_BOOLEAN_TRUE };
result = (*mSlEngineInterface)->CreateOutputMix(mSlEngineInterface, &mSlOutputMixObject, numWantedInterfaces, wantedInterfaces, wantedInterfacesRequired);
SLuint32 const numWantedInterfaces = 0;
result = (*mSlEngineInterface)->CreateOutputMix(mSlEngineInterface, &mSlOutputMixObject, numWantedInterfaces, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
result = (*mSlOutputMixObject)->Realize(mSlOutputMixObject, SL_BOOLEAN_FALSE);
@ -73,7 +82,7 @@ void opensl_prefetch_callback(SLPrefetchStatusItf caller, void* pContext, SLuint
(*caller)->GetPrefetchStatus(caller, &status);
if (status == SL_PREFETCHSTATUS_UNDERFLOW) {
// Level is 0 but we have SL_PREFETCHSTATUS_UNDERFLOW, implying an error.
printf("- ERROR: Underflow when prefetching data and fill level zero\n");
printf("play-audio: underflow when prefetching data\n");
MutexWithCondition* cond = (MutexWithCondition*) pContext;
cond->lockAndSignal();
}
@ -95,16 +104,10 @@ void AudioPlayer::play(char const* uri)
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, mSlOutputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// SL_IID_ANDROIDCONFIGURATION is Android specific interface, SL_IID_VOLUME is general:
SLuint32 const numWantedInterfaces = 5;
SLInterfaceID wantedInterfaces[numWantedInterfaces]{
SL_IID_ANDROIDCONFIGURATION,
SL_IID_VOLUME,
SL_IID_PREFETCHSTATUS,
SL_IID_PLAYBACKRATE,
SL_IID_EFFECTSEND
};
SLboolean wantedInterfacesRequired[numWantedInterfaces]{ SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
// SL_IID_ANDROIDCONFIGURATION is Android specific interface, SL_IID_PREFETCHSTATUS is general:
SLuint32 const numWantedInterfaces = 2;
SLInterfaceID wantedInterfaces[numWantedInterfaces]{ SL_IID_ANDROIDCONFIGURATION, SL_IID_PREFETCHSTATUS };
SLboolean wantedInterfacesRequired[numWantedInterfaces]{ SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
SLObjectItf uriPlayerObject = NULL;
SLresult result = (*mSlEngineInterface)->CreateAudioPlayer(mSlEngineInterface, &uriPlayerObject, &audioSrc, &audioSnk,
@ -119,21 +122,7 @@ void AudioPlayer::play(char const* uri)
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_ANDROIDCONFIGURATION, &androidConfig);
assert(SL_RESULT_SUCCESS == result);
// This allows setting the stream type (default:SL_ANDROID_STREAM_MEDIA):
/* same as android.media.AudioManager.STREAM_VOICE_CALL */
// #define SL_ANDROID_STREAM_VOICE ((SLint32) 0x00000000)
/* same as android.media.AudioManager.STREAM_SYSTEM */
// #define SL_ANDROID_STREAM_SYSTEM ((SLint32) 0x00000001)
/* same as android.media.AudioManager.STREAM_RING */
// #define SL_ANDROID_STREAM_RING ((SLint32) 0x00000002)
/* same as android.media.AudioManager.STREAM_MUSIC */
// #define SL_ANDROID_STREAM_MEDIA ((SLint32) 0x00000003)
/* same as android.media.AudioManager.STREAM_ALARM */
// #define SL_ANDROID_STREAM_ALARM ((SLint32) 0x00000004)
/* same as android.media.AudioManager.STREAM_NOTIFICATION */
// #define SL_ANDROID_STREAM_NOTIFICATION ((SLint32) 0x00000005)
SLint32 androidStreamType = SL_ANDROID_STREAM_ALARM;
result = (*androidConfig)->SetConfiguration(androidConfig, SL_ANDROID_KEY_STREAM_TYPE, &androidStreamType, sizeof(SLint32));
result = (*androidConfig)->SetConfiguration(androidConfig, SL_ANDROID_KEY_STREAM_TYPE, &this->androidStreamType, sizeof(SLint32));
assert(SL_RESULT_SUCCESS == result);
// We now Realize(). Note that the android config needs to be done before, but getting the SLPrefetchStatusItf after.
@ -148,10 +137,6 @@ void AudioPlayer::play(char const* uri)
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_PLAY, &uriPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
SLPlaybackRateItf playbackRateInterface;
result = (*uriPlayerObject)->GetInterface(uriPlayerObject, SL_IID_PLAYBACKRATE, &playbackRateInterface);
assert(SL_RESULT_SUCCESS == result);
if (NULL == uriPlayerPlay) {
fprintf(stderr, "Cannot play '%s'\n", uri);
} else {
@ -194,19 +179,53 @@ int main(int argc, char** argv)
{
bool help = false;
int c;
while ((c = getopt(argc, argv, "h")) != -1) {
char* streamType = NULL;
while ((c = getopt(argc, argv, "hs:")) != -1) {
switch (c) {
case 'h': help = true; break;
case 'h':
case '?': help = true; break;
case 's': streamType = optarg; break;
}
}
if (help || optind == argc) {
printf("usage: %s [files]\n", argv[0]);
exit(0);
printf("usage: play-audio [-s streamtype] [files]\n");
return 1;
}
AudioPlayer player;
for (int i = optind; i < argc; i++) player.play(argv[i]);
if (streamType != NULL) {
SLint32 streamTypeEnum;
if (strcmp("alarm", streamType) == 0) {
streamTypeEnum = SL_ANDROID_STREAM_ALARM;
} else if (strcmp("media", streamType) == 0) {
streamTypeEnum = SL_ANDROID_STREAM_MEDIA;
} else if (strcmp("notification", streamType) == 0) {
streamTypeEnum = SL_ANDROID_STREAM_NOTIFICATION;
} else if (strcmp("ring", streamType) == 0) {
streamTypeEnum = SL_ANDROID_STREAM_RING;
} else if (strcmp("system", streamType) == 0) {
streamTypeEnum = SL_ANDROID_STREAM_SYSTEM;
} else if (strcmp("voice", streamType) == 0) {
streamTypeEnum = SL_ANDROID_STREAM_VOICE;
} else {
fprintf(stderr, "play-audio: invalid streamtype '%s'\n", streamType);
return 1;
}
player.setStreamType(streamTypeEnum);
}
for (int i = optind; i < argc; i++) {
if (access(argv[i], R_OK) != 0) {
fprintf(stderr, "play-audio: '%s' is not a readable file\n", argv[i]);
return 1;
}
}
for (int i = optind; i < argc; i++) {
player.play(argv[i]);
}
return 0;
}

Loading…
Cancel
Save