Estoy trabajando en un programa de Android que necesita reproducir archivos de audio repetidamente con un tiempo muy exacto (programa de música).AudioTrack solo reproducirá audio una vez
Estoy usando un "AudioTrack" en este momento que tiene los datos PCM cargados desde una muestra WAV.
aquí está el código con el que estoy probando esta característica. simplemente gira hasta que es hora de reproducir la muestra, luego la reproduce y repite esto 8 veces.
Aquí está el código que estoy usando, hágamelo saber si usted necesita ver más:
class Sequencer {
private final double BPM = 120;
private final double BPMS = (BPM/60/1000);
private long QUARTER_NOTE_DELAY = (long)(1/BPMS);
private final int PCM_BYTE_OFFSET = 44;
private long lastTick;
private long now = 0;
private int sampleRate = 8000;
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private int bufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat)*5;
private AudioTrack playbackBuffer = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,
channelConfig,audioFormat,bufferSize,AudioTrack.MODE_STATIC);;
private byte[] pcmArray;
public Sequencer()
{
Log.d("AudioTrack", "BUFFER SIZE: " +bufferSize);
String path = "samples/classical_guitar_c5_16bit.wav";
try {
pcmArray = parsePCMData(path);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("Error Initializng Sequencer", "File not Found: " + path);
e.printStackTrace();
}
}
public void play() {
new Thread() {
public void run() {
lastTick = 0;
// play 10 times
Log.d("Sequencer", "QUARTER-NOTE = " + QUARTER_NOTE_DELAY + "ms");
for (int i = 0; i < 8; i++)
{
lastTick = System.currentTimeMillis();
while (!update(i));
}
playbackBuffer.flush();
}
}.start();
}
public void stop() {
}
//load PCM data into the buffer
private void loadPCMData(byte[] pcmData)
{
int numBytesWritten = playbackBuffer.write(pcmData, PCM_BYTE_OFFSET, (pcmData.length-PCM_BYTE_OFFSET));
Log.d("AudioTrack", "LOADED " + numBytesWritten + " BYTES" + " IN " + (System.currentTimeMillis()- now) + "ms!");
}
private byte[] parsePCMData(String path) throws IOException
{
InputStream fileIn = assetManager.open(path);
BufferedInputStream buffIn = new BufferedInputStream(fileIn, 8000);
DataInputStream dataIn = new DataInputStream(buffIn);
byte[] pcmArray;
ArrayList<Byte> pcmVector = new ArrayList<Byte>();
int numBytes;
//Read the file into the "music" array
for(int i=0; dataIn.available() > 0; i++)
{
pcmVector.add(dataIn.readByte());
}
//Close the input streams
dataIn.close();
buffIn.close();
fileIn.close();
numBytes = pcmVector.size();
pcmArray = new byte[numBytes];
//Copy the data from the arrayLast to the byte array
for(int i=0; i<numBytes; i++)
{
pcmArray[i] = (Byte) pcmVector.get(i);
}
return pcmArray;
}
//Start Playback of PCM data
private void startPlayback()
{
//stop playback
if(playbackBuffer.getState() != AudioTrack.STATE_NO_STATIC_DATA)
{
playbackBuffer.stop();
playbackBuffer.flush();
}
//start loading the next batch of sounds
loadPCMData(pcmArray);
//reset head position
playbackBuffer.setPlaybackHeadPosition(0);
//playbacksounds
playbackBuffer.play();
}
private boolean update(int i) {
now = System.currentTimeMillis();
if (now - lastTick >= QUARTER_NOTE_DELAY) {
//start Sounds
Log.d("AudioTrack: ", "Starting Playback. Current State: " + Integer.toString(playbackBuffer.getState()));
startPlayback();
Log.d("AudioTrack: ", "Playback Started. Current State: " + Integer.toString(playbackBuffer.getState()));
Log.d("MainMenu.java: ", "Event Triggered after " + Long.toString(now-lastTick) +"ms");
lastTick = now;
//update UI in a seperate thread
beatCounter.post(updateUI);
return true;
}
else{
return false;
}
}
}
Se juega perfectamente en el primero de los ocho bucles, pero después de eso sólo hay silencio, sin errores o advertencias visibles. (aunque el estado permanecerá en 1, que es "STATE_INITIALIZED" que significa "Estado de un AudioTrack que está listo para usarse".
Soy consciente de que AudioTrack tiene una función de bucle, así como el método "reloadStaticData", pero cuando comienzo a escribir la aplicación real, estoy probando esto para que los datos cambien cada vez según una secuencia generada por el usuario)
Además, inicialmente intenté hacer esto tanto con mediaplayer como con soundpool, pero ambos me dieron demasiada latencia
Como prueba también lo intenté con la reinicialización del AudioTrack completamente en cada ciclo, pero eso me dio demasiada latencia para ser realmente útil.
Me disculpo por el código desordenado, realmente espero que sea algo estúpido que estoy haciendo mal, ya que me estoy frustrando mucho.
Gracias!
prueba en Android 2.2.2, en un dispositivo terminal inalámbrico (no emulado)
Aquí está mi salida LogCat:
10-01 05:07:22.016: DEBUG/AndroidRuntime(23316): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
10-01 05:07:22.016: DEBUG/AndroidRuntime(23316): CheckJNI is OFF
10-01 05:07:22.016: DEBUG/dalvikvm(23316): creating instr width table
10-01 05:07:22.094: DEBUG/AndroidRuntime(23316): --- registering native functions ---
10-01 05:07:22.461: DEBUG/dalvikvm(22329): GC_EXPLICIT freed 236 objects/13984 bytes in 39ms
10-01 05:07:23.547: DEBUG/PackageParser(1089): Scanning package: /data/app/vmdl67886.tmp
10-01 05:07:23.680: DEBUG/KeyguardViewMediator(1089): wakeWhenReadyLocked(26)
10-01 05:07:23.680: DEBUG/KeyguardViewMediator(1089): handleWakeWhenReady(26)
10-01 05:07:23.680: DEBUG/KeyguardViewMediator(1089): pokeWakelock(5000)
10-01 05:07:23.680: INFO/power(1089): *** set_screen_state 1
10-01 05:07:23.696: DEBUG/Sensors(1089): using sensors (name=sensors)
10-01 05:07:24.088: INFO/PackageManager(1089): Removing non-system package:com.android.test
10-01 05:07:24.088: INFO/Process(1089): Sending signal. PID: 23293 SIG: 9
10-01 05:07:24.088: INFO/ActivityManager(1089): Force stopping package com.android.test uid=10081
10-01 05:07:24.102: INFO/WindowManager(1089): WIN DEATH: Window{44b41118 com.android.test/com.android.test.MainMenu paused=false}
10-01 05:07:24.118: INFO/UsageStats(1089): Unexpected resume of com.android.launcher while already resumed in com.android.test
10-01 05:07:24.196: DEBUG/SurfaceFlinger(1089): Screen about to return, flinger = 0x120f38
10-01 05:07:24.446: DEBUG/PackageManager(1089): Scanning package com.android.test
10-01 05:07:24.446: INFO/PackageManager(1089): Package com.android.test codePath changed from /data/app/com.android.test-2.apk to /data/app/com.android.test-1.apk; Retaining data and using new
10-01 05:07:24.453: INFO/PackageManager(1089): /data/app/com.android.test-1.apk changed; unpacking
10-01 05:07:24.453: DEBUG/installd(1012): DexInv: --- BEGIN '/data/app/com.android.test-1.apk' ---
10-01 05:07:24.602: DEBUG/dalvikvm(23325): creating instr width table
10-01 05:07:24.641: DEBUG/dalvikvm(23325): DexOpt: load 11ms, verify 23ms, opt 0ms
10-01 05:07:24.649: DEBUG/installd(1012): DexInv: --- END '/data/app/com.android.test-1.apk' (success) ---
10-01 05:07:24.657: DEBUG/PackageManager(1089): Activities: com.android.test.AndroidTestActivity com.android.test.MainMenu
10-01 05:07:24.657: INFO/ActivityManager(1089): Force stopping package com.android.test uid=10081
10-01 05:07:24.657: WARN/PackageManager(1089): Code path for pkg : com.android.test changing from /data/app/com.android.test-2.apk to /data/app/com.android.test-1.apk
10-01 05:07:24.657: WARN/PackageManager(1089): Resource path for pkg : com.android.test changing from /data/app/com.android.test-2.apk to /data/app/com.android.test-1.apk
10-01 05:07:24.829: INFO/installd(1012): move /data/dalvik-cache/[email protected]@[email protected] -> /data/dalvik-cache/[email protected]@[email protected]
10-01 05:07:24.829: DEBUG/PackageManager(1089): New package installed in /data/app/com.android.test-1.apk
10-01 05:07:24.868: DEBUG/KeyguardViewMediator(1089): pokeWakelock(5000)
10-01 05:07:25.000: DEBUG/KeyguardViewMediator(1089): pokeWakelock(5000)
10-01 05:07:25.211: WARN/InputManagerService(1089): Got RemoteException sending setActive(false) notification to pid 23293 uid 10081
10-01 05:07:25.274: INFO/ActivityManager(1089): Force stopping package com.android.test uid=10081
10-01 05:07:25.571: DEBUG/dalvikvm(1089): GC_EXPLICIT freed 24967 objects/1341840 bytes in 159ms
10-01 05:07:25.672: DEBUG/VoiceDialerReceiver(22354): onReceive Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.android.test flg=0x10000000 cmp=com.android.voicedialer/.VoiceDialerReceiver (has extras) }
10-01 05:07:25.977: DEBUG/dalvikvm(1089): GC_EXPLICIT freed 6005 objects/330448 bytes in 141ms
10-01 05:07:26.016: DEBUG/VoiceDialerReceiver(22354): onReceive Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.android.test flg=0x10000000 cmp=com.android.voicedialer/.VoiceDialerReceiver (has extras) }
10-01 05:07:26.250: INFO/installd(1012): unlink /data/dalvik-cache/[email protected]@[email protected]
10-01 05:07:26.258: DEBUG/AndroidRuntime(23316): Shutting down VM
10-01 05:07:26.266: DEBUG/dalvikvm(23316): Debugger has detached; object registry had 1 entries
10-01 05:07:26.282: INFO/AndroidRuntime(23316): NOTE: attach of thread 'Binder Thread #3' failed
10-01 05:07:26.680: DEBUG/AndroidRuntime(23330): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
10-01 05:07:26.680: DEBUG/AndroidRuntime(23330): CheckJNI is OFF
10-01 05:07:26.680: DEBUG/dalvikvm(23330): creating instr width table
10-01 05:07:26.735: DEBUG/AndroidRuntime(23330): --- registering native functions ---
10-01 05:07:27.047: INFO/ActivityManager(1089): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.android.test/.AndroidTestActivity }
10-01 05:07:27.110: DEBUG/AndroidRuntime(23330): Shutting down VM
10-01 05:07:27.110: DEBUG/dalvikvm(23330): Debugger has detached; object registry had 1 entries
10-01 05:07:27.110: INFO/ActivityManager(1089): Start proc com.android.test for activity com.android.test/.AndroidTestActivity: pid=23337 uid=10081 gids={}
10-01 05:07:27.125: INFO/AndroidRuntime(23330): NOTE: attach of thread 'Binder Thread #3' failed
10-01 05:07:27.203: INFO/WindowManager(1089): Setting rotation to 1, animFlags=1
10-01 05:07:27.227: INFO/ActivityManager(1089): Config changed: { scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=2 layout=34 uiMode=17 seq=554}
10-01 05:07:27.613: INFO/ActivityManager(1089): Displayed activity com.android.test/.AndroidTestActivity: 513 ms (total 513 ms)
10-01 05:07:27.657: WARN/IInputConnectionWrapper(17894): showStatusIcon on inactive InputConnection
10-01 05:07:28.073: INFO/ActivityManager(1089): Starting activity: Intent { act=com.android.test.CLEARSPLASH cmp=com.android.test/.MainMenu }
10-01 05:07:28.141: DEBUG/AudioTrack(23337): BUFFER SIZE: 14860
10-01 05:07:28.571: INFO/ActivityManager(1089): Displayed activity com.android.test/.MainMenu: 488 ms (total 488 ms)
10-01 05:07:29.930: DEBUG/dalvikvm(1089): GC_EXPLICIT freed 3588 objects/165776 bytes in 182ms
10-01 05:07:40.172: DEBUG/Sequencer(23337): QUARTER-NOTE = 500ms
10-01 05:07:40.680: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 2
10-01 05:07:40.680: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:40.688: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:40.688: DEBUG/MainMenu.java:(23337): Event Triggered after 502ms
10-01 05:07:41.203: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:41.203: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:41.203: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:41.203: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:41.711: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:41.711: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:41.719: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:41.719: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:42.227: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:42.235: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:42.235: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:42.235: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:42.743: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:42.743: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:42.750: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:42.750: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:43.258: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:43.258: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:43.258: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:43.258: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:43.774: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:43.774: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 1ms!
10-01 05:07:43.782: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:43.782: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:44.289: DEBUG/AudioTrack:(23337): Starting Playback. Current State: 1
10-01 05:07:44.297: DEBUG/AudioTrack(23337): LOADED 14860 BYTES IN 2ms!
10-01 05:07:44.305: DEBUG/AudioTrack:(23337): Playback Started. Current State: 1
10-01 05:07:44.305: DEBUG/MainMenu.java:(23337): Event Triggered after 500ms
10-01 05:07:44.344: DEBUG/dalvikvm(22433): GC_EXPLICIT freed 827 objects/40752 bytes in 67ms
10-01 05:07:49.422: DEBUG/dalvikvm(20018): GC_EXPLICIT freed 596 objects/30440 bytes in 67ms
10-01 05:07:54.563: DEBUG/dalvikvm(22329): GC_EXPLICIT freed 143 objects/10072 bytes in 80ms
10-01 05:07:59.696: DEBUG/dalvikvm(22354): GC_EXPLICIT freed 547 objects/30048 bytes in 68ms
10-01 05:08:09.977: DEBUG/dalvikvm(22363): GC_EXPLICIT freed 483 objects/22512 bytes in 111ms
10-01 05:08:10.219: INFO/power(1089): *** set_screen_state 0
10-01 05:08:10.237: DEBUG/SurfaceFlinger(1089): About to give-up screen, flinger = 0x120f38
10-01 05:08:10.258: DEBUG/Sensors(1089): using accelerometer (name=accelerometer)
10-01 05:08:15.430: DEBUG/StatusBar(1089): DISABLE_EXPAND: yes
10-01 05:08:15.469: DEBUG/GoogleLoginService(16965): onBind: Intent { act=android.accounts.AccountAuthenticator cmp=com.google.android.gsf/.loginservice.GoogleLoginService }
10-01 05:08:15.469: INFO/WindowManager(1089): Setting rotation to 0, animFlags=1
10-01 05:08:15.493: INFO/ActivityManager(1089): Config changed: { scale=1.0 imsi=310/4 loc=en_US touch=3 keys=2/1/2 nav=2/2 orien=1 layout=34 uiMode=17 seq=555}
10-01 05:08:15.821: DEBUG/dalvikvm(23337): GC_FOR_MALLOC freed 1766 objects/427920 bytes in 193ms
10-01 05:08:15.899: DEBUG/AudioTrack(23337): BUFFER SIZE: 14860
¿Por qué bucle durante 8 veces? verifique esta línea: 'for (int i = 0; i <8; i ++)' – iTurki