jni - Lame encoded mp3 audio slowed down - Android -


i have been following this tutorial on using lame mp3 on android jni. recording seems working , getting output mp3 upon playback audio has been slowed down , pitched down.

i've tried put pertinent code below. guidance on why happening? in advance help.

edit: ok check imported raw data audacity , plays fine must issue @ encoding stage.

java class:

public class record extends activity implements onclicklistener {      static {         system.loadlibrary("mp3lame");     }      private native void initencoder(int numchannels, int samplerate, int bitrate, int mode, int quality);      private native void destroyencoder();      private native int encodefile(string sourcepath, string targetpath);      private static final int recorder_bpp = 16;     private static final string audio_recorder_file_ext_wav = ".wav";     private static final string audio_recorder_folder = "aberdeensoundsites";     private static final string audio_recorder_temp_file = "record_temp.raw";     private static final int[] recorder_samplerates = {44100, 22050, 11025, 8000};     private static final int recorder_channels = audioformat.channel_in_stereo;     private static final int recorder_audio_encoding = audioformat.encoding_pcm_16bit;      public static final int num_channels = 2;     public static final int sample_rate = 44100;     public static final int bitrate = 320;     public static final int mode = 1;     public static final int quality = 2;         private short[] mbuffer;     private file rawfile;     private file encodedfile;      private int samplerate;     private string filename;      private audiorecord recorder = null;     private int buffersize = 0;     private thread recordingthread = null;     private boolean isrecording = false;       @override     public void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.record);          initencoder(num_channels, sample_rate, bitrate, mode, quality);          stopbutton = (button) findviewbyid(r.id.stop_button);         stopbutton.setonclicklistener(this);         timer = (textview) findviewbyid(r.id.recording_time);          buffersize = audiorecord.getminbuffersize(44100, recorder_channels, recorder_audio_encoding);     }      private void startrecording() {         stopped = false;         stopbutton.settext(r.string.stop_button_label);          // set , start audio recording         recorder = findaudiorecord();         recorder.startrecording();         isrecording = true;          rawfile = getfile("raw");         mbuffer = new short[buffersize];         startbufferedwrite(rawfile);         }      private void stoprecording() {         mhandler.removecallbacks(starttimer);         stopped = true;          if(recorder != null){             isrecording = false;              recorder.stop();             recorder.release();              recorder = null;             recordingthread = null;         }          encodedfile = getfile("mp3");         int result = encodefile(rawfile.getabsolutepath(), encodedfile.getabsolutepath());         if (result == 0) {             toast.maketext(record.this, "encoded " + encodedfile.getname(), toast.length_short)                     .show();         }     }      private void startbufferedwrite(final file file) {         new thread(new runnable() {             @override             public void run() {                 looper.prepare();                 dataoutputstream output = null;                 try {                     output = new dataoutputstream(new bufferedoutputstream(new fileoutputstream(file)));                     while (isrecording) {                         int readsize = recorder.read(mbuffer, 0, mbuffer.length);                         (int = 0; < readsize; i++) {                             output.writeshort(mbuffer[i]);                         }                     }                 } catch (ioexception e) {                     toast.maketext(record.this, e.getmessage(), toast.length_short).show();                 } {                     if (output != null) {                         try {                             output.flush();                         } catch (ioexception e) {                             toast.maketext(record.this, e.getmessage(), toast.length_short).show();                         } {                             try {                                 output.close();                             } catch (ioexception e) {                                 toast.maketext(record.this, e.getmessage(), toast.length_short).show();                             }                         }                     }                 }             }         }).start();     }      private file getfile(final string suffix) {         time time = new time();         time.settonow();         return new file(environment.getexternalstoragedirectory()+"/myappfolder", time.format("%y%m%d%h%m%s") + "." + suffix);     }      public audiorecord findaudiorecord() {         (int rate : recorder_samplerates) {             (short audioformat : new short[] { audioformat.encoding_pcm_16bit, audioformat.encoding_pcm_8bit }) {                 (short channelconfig : new short[] { audioformat.channel_in_stereo, audioformat.channel_in_mono  }) {                     try {                         log.d("aberdeensoundsites", "attempting rate " + rate + "hz, bits: " + audioformat + ", channel: "                                 + channelconfig);                         int buffersize = audiorecord.getminbuffersize(rate, channelconfig, audioformat);                          if (buffersize != audiorecord.error_bad_value) {                             // check if can instantiate , have success                             audiorecord recorder = new audiorecord(mediarecorder.audiosource.mic, rate, channelconfig, audioformat, buffersize);                             samplerate = rate;                             if (recorder.getstate() == audiorecord.state_initialized)                                 return recorder;                         }                     } catch (exception e) {                         log.e("myapp", rate + "exception, keep trying.",e);                     }                 }             }         }         log.e("myapp", "no settings worked :(");         return null;     } 

c wrapper:

#include <stdio.h> #include <stdlib.h> #include <jni.h> #include <android/log.h>  #include "libmp3lame/lame.h"  #define log_tag "lame encoder" #define logd(format, args...)  __android_log_print(android_log_debug, log_tag, format, ##args); #define buffer_size 8192 #define be_short(s) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8))  lame_t lame;  int read_samples(file *input_file, short *input) {     int nb_read;     nb_read = fread(input, 1, sizeof(short), input_file) / sizeof(short);      int = 0;     while (i < nb_read) {         input[i] = be_short(input[i]);         i++;     }      return nb_read; }  void java_mypacakage_myapp_record_initencoder(jnienv *env,         jobject jobj, jint in_num_channels, jint in_samplerate, jint in_brate,         jint in_mode, jint in_quality) {     lame = lame_init();      logd("init parameters:");     lame_set_num_channels(lame, in_num_channels);     logd("number of channels: %d", in_num_channels);     lame_set_in_samplerate(lame, in_samplerate);     logd("sample rate: %d", in_samplerate);     lame_set_brate(lame, in_brate);     logd("bitrate: %d", in_brate);     lame_set_mode(lame, in_mode);     logd("mode: %d", in_mode);     lame_set_quality(lame, in_quality);     logd("quality: %d", in_quality);      int res = lame_init_params(lame);     logd("init returned: %d", res); }  void java_mypacakage_myapp_record_destroyencoder(         jnienv *env, jobject jobj) {     int res = lame_close(lame);     logd("deinit returned: %d", res); }  void java_mypacakage_myapp_record_encodefile(jnienv *env,         jobject jobj, jstring in_source_path, jstring in_target_path) {     const char *source_path, *target_path;     source_path = (*env)->getstringutfchars(env, in_source_path, null);     target_path = (*env)->getstringutfchars(env, in_target_path, null);      file *input_file, *output_file;     input_file = fopen(source_path, "rb");     output_file = fopen(target_path, "wb");      short input[buffer_size];     char output[buffer_size];     int nb_read = 0;     int nb_write = 0;     int nb_total = 0;      logd("encoding started");     while (nb_read = read_samples(input_file, input)) {         nb_write = lame_encode_buffer(lame, input, input, nb_read, output,                 buffer_size);         fwrite(output, nb_write, 1, output_file);         nb_total += nb_write;     }     logd("encoded %d bytes", nb_total);      nb_write = lame_encode_flush(lame, output, buffer_size);     fwrite(output, nb_write, 1, output_file);     logd("flushed %d bytes", nb_write);      fclose(input_file);     fclose(output_file); } 

edit - ok out of interest downloaded apk tutorial provides phone , ran it. works fine. suggest problem less tutorial , more i've done. re-look on when have time available , see if can determine went wrong

you call initencoder 2 channels, , initialize audiorecord stereo , mono, wrapper.c can deal 1 channel:

  nb_write = lame_encode_buffer(lame, input, input, nb_read, output, buffer_size);  

the above codes require source audio mono 1 channel. if want support stereo, pay attention lame_encode_buffer method

  int cdecl lame_encode_buffer (                                                                                                                                     lame_global_flags*  gfp,           /* global context handle         */                                                                                     const short int     buffer_l [],   /* pcm data left channel     */                                                                                     const short int     buffer_r [],   /* pcm data right channel    */                                                                                     const int           nsamples,      /* number of samples per channel */                                                                                     unsigned char*      mp3buf,        /* pointer encoded mp3 stream */                                                                                     const int           mp3buf_size ); /* number of valid octets in                                                                                                                             stream                        */  

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -