Commit e6cc5bf9 authored by hanriaca's avatar hanriaca

tmp : adding saveCurrentState function into respeaking mode

fix progressBar / textviews when  we save a session for check mode

Adding modifications to sharedPreferences

tmp push to work this week end

save current session for respeaking mode

adding smapleRate into sharedPreferencesobject + better organisation of code

Tmp commit to get the code at home

last modifs

Save elicitation session works + save respeaking session.
parent bb8131e5
......@@ -22,7 +22,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_undo_black_24dp"
android:onClick="onBackPressed"
android:onClick="onButtonBackPressed"
android:text="@string/goBack"
android:textColor="#D32F2F"
android:layout_marginBottom="20dp"
......
......@@ -121,5 +121,20 @@
<string name="sessionCheckExportFile">checkExportFile</string>
<string name="sessionInputFile">inputFile</string>
<string name="mexico">Ex : Mexico</string>
<string name="sessionOutputFile">session_output_file</string>
<string name="sessionSelectedMode">selected_mode</string>
<string name="randomUUID">random_uuid</string>
<string name="dirname">dirname</string>
<string name="rewindAmount">rewindAmount</string>
<string name="languageCode">LanguageCode</string>
<string name="languageName">languageName</string>
<string name="languageMotherCode">languageMotherCode</string>
<string name="languageMotherName">languageMotherName</string>
<string name="serializedMapper">serializedMapper</string>
<string name="totalAudioLength">totalAutioLength</string>
<string name="payLoadSize">payLoadaSize</string>
<string name="currentPCMSample">currentPCMSample</string>
<string name="sampleRate">sampleRate</string>
<string name="currentLine">currentLine</string>
<string name="elicitTextFile">elicitTextFile</string>
</resources>
......@@ -222,7 +222,11 @@ public class ModeSelection extends Activity implements OnClickListener{
intent = new Intent(getActivity(), CheckTranscription.class);
} else if (mode.compareToIgnoreCase(CheckWordVariant.TAG) == 0) {
intent = new Intent(getActivity(), CheckWordVariant.class);
} else {
} else if (mode.compareToIgnoreCase(ThumbRespeakActivityLig.TAG) == 0) {
intent = new Intent(getActivity(), ThumbRespeakActivityLig.class);
} else if (mode.compareToIgnoreCase(RecordElicitation.TAG) == 0) {
intent = new Intent(getActivity(), RecordElicitation.class);
}else {
Toast.makeText(getActivity(), "An error ocurred, the session could not be retrieved", Toast.LENGTH_LONG).show();
return;
}
......
......@@ -6,7 +6,12 @@ package org.lp20.aikuma.audio.record;
import android.util.Log;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.UUID;
import org.lp20.aikuma.audio.Sampler;
......@@ -21,11 +26,13 @@ import org.lp20.aikuma.model.Recording;
* @author Oliver Adams <oliver.adams@gmail.com>
* @author Florian Hanke <florian.hanke@gmail.com>
*/
public class Mapper {
public class Mapper implements Serializable {
/** The segment mapping between the original and the respeaking. */
private Segments segments;
private BufferedReader reader;
/**
* Temporarily store the boundaries of segments before being put in
* segments */
......@@ -45,6 +52,16 @@ public class Mapper {
public Mapper(UUID uuid) {
this.segments = new Segments();
this.mappingFile = new File(Recording.getNoSyncRecordingsPath(), uuid + ".map");
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(this.mappingFile)));
restoreFromMappingFile();
Log.d("mapper generation", "yes");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public File getMapFile() {
......@@ -77,6 +94,24 @@ public class Mapper {
return 0L;
}
}
private void restoreFromMappingFile() throws IOException {
String line;
while ((line = reader.readLine()) != null && (line.isEmpty() || line.split(":").length <= 1)) { continue; }
Log.d("line", line);
do {
String[] pair = line.split(":");
String[] strFirstSeg = pair[0].split(",");
String[] strSecondSeg = pair[1].split(",");
Segment original = new Segment(Long.parseLong(strFirstSeg[0]), Long.parseLong(strFirstSeg[1]));
Log.d("original seg ", original.getStartSample() + " -> " + original.getEndSample());
Segment rspkSeg = new Segment(Long.parseLong(strSecondSeg[0]), Long.parseLong(strSecondSeg[1]));
Log.d("rspkSeg seg ", rspkSeg.getStartSample() + " -> " + rspkSeg.getEndSample());
segments.put(original, rspkSeg);
Log.d("segments size", ""+segments.getSegmentMap().size());
originalStartOfSegment = original.getEndSample();
} while((line = reader.readLine()) != null && !line.isEmpty() && line.split(":").length > 1);
}
/**
* Marks the start of an original segment.
......@@ -89,6 +124,7 @@ public class Mapper {
// originalStartOfSegment
if (originalEndOfSegment != null) {
originalStartOfSegment = original.getCurrentSample();
Log.d("mark", "mark original segment : " + original.getCurrentSample());
}
}
......
......@@ -95,6 +95,25 @@ public class PCMWriter implements Sampler {
return this.fullFilename;
}
public int getPayloadSize() {
return payloadSize;
}
public void setPayloadSize(int payloadSize) {
this.payloadSize = payloadSize;
}
public void setCurrentSample(long currentSample) {
this.currentSample = currentSample;
}
public RandomAccessFile getRandomAccessWriter() {
return randomAccessWriter;
}
/**
* Write the given byte buffer to the file.
*
......@@ -111,6 +130,7 @@ public class PCMWriter implements Sampler {
// Remember larger payload.
//
payloadSize += buffer.length;
Log.d("payLoadSize", "payLoadSize = " + payloadSize);
} catch (IOException e) {
Log.e(PCMWriter.class.getName(),
"Error occured in updateListener, recording is aborted");
......@@ -118,6 +138,7 @@ public class PCMWriter implements Sampler {
if (sampleSize == 16) {
this.currentSample += buffer.length / 2;
Log.d("currentSaple", "currentSample = " + this.currentSample);
} else {
//Assume sample size is 8.
this.currentSample += buffer.length;
......@@ -141,15 +162,12 @@ public class PCMWriter implements Sampler {
*/
public void write(short[] buffer, int len) {
byte[] byteBuffer = new byte[len * 2];
for (int i = 0; i < len; i++) {
short sample = buffer[i];
// TODO Use Java helpers?
byteBuffer[i * 2] = (byte) sample;
byteBuffer[i * 2 + 1] = (byte) (sample >>> 8);
}
write(byteBuffer);
}
......@@ -230,70 +248,82 @@ public class PCMWriter implements Sampler {
*/
public void prepare(String fullFilename) {
this.fullFilename = fullFilename;
Log.d("targetFileName", "targetFileName = " + fullFilename);
try {
File f = new File(fullFilename);
Boolean exists = f.exists();
/*if (exists && fullFilename.contains("no-sync")) {
String[] p2 = fullFilename.split(".wav");
fullFilename = p2[0]+"(1)"+p2[1];
Log.d("new full", "targetFileName => "+fullFilename);
}*/
createRandomAccessFile(fullFilename);
// Write the full WAV PCM file header.
//
// Set file length to 0, to prevent unexpected
// behaviour in case the file already existed.
//
randomAccessWriter.setLength(0);
// "RIFF" announcement.
//
randomAccessWriter.writeBytes("RIFF");
// File size, 0 = unknown.
//
randomAccessWriter.writeInt(0);
// "WAVE fmt " = WAV format.
//
randomAccessWriter.writeBytes("WAVE");
randomAccessWriter.writeBytes("fmt ");
// Sub-chunk size, 16 = PCM.
//
randomAccessWriter.writeInt(Integer.reverseBytes(16));
// AudioFormat, 1 = PCM.
//
randomAccessWriter.writeShort(Short.reverseBytes((short) 1));
// Number of channels, 1 = mono, 2 = stereo.
//
randomAccessWriter.writeShort(
Short.reverseBytes(numberOfChannels));
// Sample rate.
//
randomAccessWriter.writeInt(Integer.reverseBytes(sampleRate));
// Byte rate = SampleRate * NumberOfChannels * BitsPerSample / 8.
//
randomAccessWriter.writeInt(Integer.reverseBytes(sampleRate
* sampleSize * numberOfChannels / 8));
// Block align = NumberOfChannels * BitsPerSample / 8.
//
randomAccessWriter.writeShort(Short .reverseBytes(
(short) (numberOfChannels * sampleSize / 8)));
// Bits per sample.
//
randomAccessWriter.writeShort(Short.reverseBytes(sampleSize));
// "data" announcement.
//
randomAccessWriter.writeBytes("data");
// Data chunk size, 0 = unknown.
//
randomAccessWriter.writeInt(0);
if (!exists) {
randomAccessWriter.setLength(0);
Log.d("passage", "targetFileName passage here for " + fullFilename);
// "RIFF" announcement.
//
randomAccessWriter.writeBytes("RIFF");
// File size, 0 = unknown.
//
randomAccessWriter.writeInt(0);
// "WAVE fmt " = WAV format.
//
randomAccessWriter.writeBytes("WAVE");
randomAccessWriter.writeBytes("fmt ");
// Sub-chunk size, 16 = PCM.
//
randomAccessWriter.writeInt(Integer.reverseBytes(16));
// AudioFormat, 1 = PCM.
//
randomAccessWriter.writeShort(Short.reverseBytes((short) 1));
// Number of channels, 1 = mono, 2 = stereo.
//
randomAccessWriter.writeShort(
Short.reverseBytes(numberOfChannels));
// Sample rate.
//
randomAccessWriter.writeInt(Integer.reverseBytes(sampleRate));
// Byte rate = SampleRate * NumberOfChannels * BitsPerSample / 8.
//
randomAccessWriter.writeInt(Integer.reverseBytes(sampleRate
* sampleSize * numberOfChannels / 8));
// Block align = NumberOfChannels * BitsPerSample / 8.
//
randomAccessWriter.writeShort(Short .reverseBytes(
(short) (numberOfChannels * sampleSize / 8)));
// Bits per sample.
//
randomAccessWriter.writeShort(Short.reverseBytes(sampleSize));
// "data" announcement.
//
randomAccessWriter.writeBytes("data");
// Data chunk size, 0 = unknown.
//
randomAccessWriter.writeInt(0);
}
// Clear the byte array.
//
// Note: Removed but here for inspiration.
......
......@@ -50,6 +50,7 @@ public class Recorder implements AudioHandler, MicrophoneListener, Sampler {
*/
public Recorder(int type, File path, long sampleRate) throws MicException {
this(type, path, sampleRate, new SimpleAnalyzer());
Log.d("Recorder", "filePath : " + path.getAbsolutePath());
}
/**
......@@ -258,14 +259,14 @@ public class Recorder implements AudioHandler, MicrophoneListener, Sampler {
*/
public void save() {
file.write(audioBuffer, audioBufLength);
Log.d("DDaudioBufLength", "audioBufferLength = "+audioBufLength);
totalAudioLength += audioBufLength;
Log.d("DDtotalAudioLength", "totalAudioLength = "+totalAudioLength);
if (this.type == 0 &&
Math.round((double) totalAudioLength / sampleRate) < Recording.SAMPLE_SEC) // 15sec sample
{
sampleFile.write(audioBuffer, audioBufLength);
}
audioBufLength = 0;
}
......@@ -324,7 +325,25 @@ public class Recorder implements AudioHandler, MicrophoneListener, Sampler {
{
sampleFile.write(buffer);
}
}
public long getTotalAudioLength() {
return totalAudioLength;
}
public void setTotalAudioLength(long totalAudioLength) {
this.totalAudioLength = totalAudioLength;
}
public PCMWriter getFile() {
return file;
}
public void setFile(PCMWriter file) {
this.file = file;
}
/**
......
......@@ -91,6 +91,7 @@ public class ThumbRespeaker {
break;
case 1: //Rewind and record the start-sample in mapper
player.seekToSample(mapper.getOriginalStartSample());
Log.d("original sample", "get original start sample : " + mapper.getOriginalStartSample());
mapper.markOriginal(player);
player.rewind(rewindAmount);
break;
......@@ -98,7 +99,9 @@ public class ThumbRespeaker {
player.seekToSample(previousEndSample);
break;
}
Log.d("previousEndSample", "previousEndSample -> " + previousEndSample/getSimplePlayer().getSampleRate());
previousEndSample = player.getCurrentSample();
Log.d("previousEndSample", "previousEndSampleAfter -> " + previousEndSample/getSimplePlayer().getSampleRate());
player.play();
}
......@@ -145,10 +148,19 @@ public class ThumbRespeaker {
// Because of rewind after each respeaking-segment,
// Force user to record respeaking after listening next original-segment
if(player.getCurrentSample() > mapper.getOriginalStartSample()) {
mapper.store(player, recorder);
Log.d("save map file", "save map file at " + mapper.getMapFile().getAbsolutePath());
mapper.store(player, recorder);
}
}
public long getPreviousEndSample() {
return previousEndSample;
}
public void setPreviousEndSample(long previousEndSample) {
this.previousEndSample = previousEndSample;
}
/**
* Stops/finishes the respeaking process
*
......@@ -170,6 +182,13 @@ public class ThumbRespeaker {
return recorder.getCurrentMsec();
}
/**
* read the mapping file and create segments.
*/
public void restoreMapper() {
}
/**
* finishedPlaying accessor
*
......@@ -198,6 +217,11 @@ public class ThumbRespeaker {
return this.player;
}
public void setMapper(Mapper mapper) {
this.mapper = mapper;
}
/**
* Releases the resources associated with this respeaker.
*/
......
......@@ -114,5 +114,11 @@ public class MetadataSession {
private void setSpeakerGender(int g) {
speakerGender = g;
}
public String toString() {
return "name : " + getSpeakerName() + " age : " + getSpeakerAge() + "speaker gender : " + getSpeakerGender() +
" region origin : " + getRegionOrigin() + " record lang : "+ getRecordLanguage().getName() +
" mother tongue : " + getMotherTongue().getName() + " rspk languages : " + getExtraLanguages().toString();
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lp20.aikuma.model;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ClassLoaderObjectInputStream;
import org.apache.commons.net.util.Base64;
public class ObjectSerializer {
public static String serialize(Serializable obj) throws IOException {
if (obj == null)
return "";
try {
ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
Deflater def = new Deflater(Deflater.BEST_COMPRESSION);
ObjectOutputStream objStream = new ObjectOutputStream(new DeflaterOutputStream(
serialObj, def));
objStream.writeObject(obj);
objStream.close();
return encodeBytes(serialObj.toByteArray());
} catch (Exception e) {
throw new IOException("Serialization error: " + e.getMessage(), e);
}
}
public static Object deserialize(String str) throws IOException {
if (str == null || str.length() == 0)
return null;
ObjectInputStream objStream = null;
try {
ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
objStream = new ClassLoaderObjectInputStream(Thread.currentThread().getContextClassLoader(), new InflaterInputStream(serialObj));
return objStream.readObject();
} catch (Exception e) {
throw new IOException("Deserialization error: " + e.getMessage(), e);
} finally {
IOUtils.closeQuietly(objStream);
}
}
public static String encodeBytes(byte[] bytes) throws UnsupportedEncodingException {
return bytes == null ? null : new String(Base64.encodeBase64(bytes), Charset.forName("UTF-8"));
}
public static byte[] decodeBytes(String str) throws UnsupportedEncodingException {
return Base64.decodeBase64(str.getBytes(Charset.forName("UTF-8")));
}
}
......@@ -83,6 +83,8 @@ public class Recording extends FileModel {
int bitsPerSample, Double latitude, Double longitude) {
super(versionName, ownerId, null, null, format);
Log.d("UUID", "UUID on constructor : "+ recordingUUID.toString());
Log.d("id", "respeakingID : " + respeakingId);
this.recordingUUID = recordingUUID;
setName(name);
setDate(date);
......
......@@ -281,7 +281,7 @@ public class RecordingLig extends Recording {
File path;
if (this.name.contains("rspk") || this.name.contains("trsl")) {
String[] dir = this.getRespeakingId().split("_");
Log.d("path -> ", this.getRespeakingId());
Log.d("path -> ", "path -> "+this.getRespeakingId());
path = new File(getRecordingsPath(),
dir[0] + "_" + dir[1] + "_" + dir[2] + "/");
} else { path = new File(getRecordingsPath(), this.name + "/"); }
......@@ -289,5 +289,4 @@ public class RecordingLig extends Recording {
Log.d("destPath", path.toString());
return path;
}
}
......@@ -8,6 +8,7 @@ import android.util.Pair;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Iterator;
import java.util.UUID;
......@@ -21,7 +22,7 @@ import org.lp20.aikuma.util.FileIO;
* @author Oliver Adams <oliver.adams@gmail.com>
* @author Florian Hanke <florian.hanke@gmail.com>
*/
public class Segments {
public class Segments implements Serializable {
/**
* Creates an object that represents a mapping of recording segments between
......@@ -135,7 +136,7 @@ public class Segments {
/**
* Represents a segment.
*/
public static class Segment {
public static class Segment implements Serializable {
private Pair<Long, Long> pair;
/**
......
......@@ -129,6 +129,11 @@ public class CheckTranscription extends AikumaActivity {
TextView tv = (TextView) findViewById(R.id.check_total_phrase_number);
tv.setText(" / " + nb_total_lines);
TextView tv2 = (TextView) findViewById(R.id.check_phrase_number);
tv2.setText("" + nbReadLines);
progressBar.setProgress((int) (((float)nbReadLines)/(float) nb_total_lines* 100));
//retrieve layout to put element in
LinearLayout llparent = (LinearLayout) findViewById(R.id.ll_variant);
llparent.removeAllViews();
......@@ -278,7 +283,6 @@ public class CheckTranscription extends AikumaActivity {
}
}
public void onValidate(View _view) {
if (saveFile()) {
......
......@@ -135,6 +135,11 @@ public class CheckWordVariant extends AikumaActivity {
TextView tv_total = (TextView) findViewById(R.id.check_total_number);
tv_total.setText(" / " + totalNumberOfExpressions);
TextView tv2 = (TextView) findViewById(R.id.check_line_number);
tv2.setText("" + nbReadLines);
progressBar.setProgress((int) (((float)nbReadLines)/(float) totalNumberOfExpressions* 100));
LinearLayout llparent = (LinearLayout) findViewById(R.id.ll_variant);
llparent.removeAllViews();
......@@ -287,8 +292,9 @@ public class CheckWordVariant extends AikumaActivity {
Log.i(TAG, "boolean value : "+wordvariant);
//si fichier non terminé alors sauver session
try {
if (reader.readLine() != null) {
/*
//if (reader.readLine() != null) {
String line;
while ((line = reader.readLine()) != null && (line.isEmpty() || line.split(", ").length <= 1)) { continue; } /*
* sauver nb lignes lues: Boolean nbReadLines
* + mode: Boolean checkMode
* + submode: Boolean checkVariant
......@@ -296,6 +302,7 @@ public class CheckWordVariant extends AikumaActivity {
* + fichier export: String variantchecked
* + date: String date
*/
Toast.makeText(this, "session saved", Toast.LENGTH_SHORT).show();
date = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.FRANCE).format(new Date());
SharedPreferences.Editor ed = prefsUserSession.edit();
ed.putBoolean(getString(R.string.sessionActive), true); //session activated
......@@ -307,7 +314,7 @@ public class CheckWordVariant extends AikumaActivity {
// ed.putBoolean(getString(R.string.checkVariant), true); //set submode
//save infos
ed.commit();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
......
......@@ -7,6 +7,7 @@ import org.lp20.aikuma2.R;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
......@@ -53,7 +54,9 @@ public class ListFileAdapter extends ArrayAdapter {
File file = new File(parentFile.getAbsolutePath()+"/"+fileName);
holder.textFileName.setText(fileName);
RelativeLayout relativeListFile = (RelativeLayout) rowView.findViewById(R.id.layoutListView);
if (!file.isDirectory()) {
Log.d("fileName : ", "fileName : " + file.getAbsolutePath());
if (fileName.contains("rspk") && fileName.contains(".wav")) {
relativeListFile.setBackgroundColor(Color.parseColor("#80673AB7"));
}
......@@ -63,7 +66,10 @@ public class ListFileAdapter extends ArrayAdapter {
relativeListFile.setBackgroundColor(Color.TRANSPARENT);
}
holder.imageType.setImageResource(R.drawable.file_icon);
holder.imagePastilleTrsl.setVisibility(ImageView.INVISIBLE);
holder.imagePastilleRspk.setVisibility(ImageView.INVISIBLE);
} else {
relativeListFile.setBackgroundColor(Color.TRANSPARENT);
ListFileTask task = new ListFileTask();
task.setHolder(holder);
task.execute(file);
......@@ -89,7 +95,7 @@ public class ListFileAdapter extends ArrayAdapter {
boolean trsl = false;
int i = 0;
holder.imageType.setImageResource(R.drawable.folder_close_icon);
while (i<files.length && (!rspk || !trsl)) {
if (files[i].getName().contains("trsl")) {
holder.imagePastilleTrsl.setVisibility(ImageView.VISIBLE);
......
......@@ -159,21 +159,6 @@ public class RespeakingSelection extends AikumaActivity {
dialog.show();
return dialog;
}
/* @Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
dismiss();
mChosenFile = mFileList[position];
Log.i("importfile", "mChosenFile: " + mChosenFile);
mPath = new File(mPath, mChosenFile);
if (mPath.isDirectory()) {
loadFileList(mPath, ".wav");
showAudioFilebrowserDialog();
} else {
fileIsNotADirectory();
}