created mirror
This commit is contained in:
37
Modules/sound/Player.java
Normal file
37
Modules/sound/Player.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Player.java
|
||||
*
|
||||
* Copyright (c) 2001, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
|
||||
package org.gzigzag.module;
|
||||
|
||||
/** A (sound/video) player that doesn't need to know
|
||||
* anything about zz.
|
||||
*/
|
||||
public interface Player {
|
||||
// this needs more stuff, hashtable ?
|
||||
// XXX getLength!!! -tjl
|
||||
void init(String file);
|
||||
void play(long from, long to, boolean loop);
|
||||
void stop();
|
||||
long getCurrentOffset();
|
||||
|
||||
}
|
||||
37
Modules/sound/Recorder.java
Normal file
37
Modules/sound/Recorder.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Recorder.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
|
||||
package org.gzigzag.module;
|
||||
|
||||
public interface Recorder {
|
||||
|
||||
// what is needed in here ???
|
||||
void init(String file, long offset);
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
long getCurrentOffset();
|
||||
|
||||
}
|
||||
65
Modules/sound/SimplePlayer.java
Normal file
65
Modules/sound/SimplePlayer.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
SimplePlayer.java
|
||||
*
|
||||
* Copyright (c) 2001, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
package org.gzigzag.module;
|
||||
import org.gzigzag.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.awt.*;
|
||||
|
||||
/** A linux sound Player using GSM compression. Requires the associated native
|
||||
* library.
|
||||
*/
|
||||
|
||||
public class SimplePlayer implements Player {
|
||||
|
||||
private int handle;
|
||||
|
||||
public void init(String file){
|
||||
handle = player_init(file);
|
||||
}
|
||||
|
||||
public void play( long from, long to, boolean loop){
|
||||
player_start(handle, from, to);
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
player_stop(handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public long getCurrentOffset(){
|
||||
return player_getCurrentOffset(handle);
|
||||
}
|
||||
|
||||
static {
|
||||
System.loadLibrary("recorder");
|
||||
}
|
||||
|
||||
private native int player_init(String file);
|
||||
private native void player_start(int handle, long from, long to);
|
||||
private native long player_getCurrentOffset(int handle);
|
||||
private native void player_stop(int handle );
|
||||
|
||||
}
|
||||
68
Modules/sound/SimpleRecorder.java
Normal file
68
Modules/sound/SimpleRecorder.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
SimpleRecorder.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
package org.gzigzag.module;
|
||||
import org.gzigzag.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Simple (linux) native recorder class to be used in
|
||||
* sound stream handling in zz.
|
||||
*/
|
||||
public class SimpleRecorder implements Recorder {
|
||||
|
||||
int handle = 0;
|
||||
|
||||
// inits recorder with a output file name
|
||||
public void init(String file, long offset){
|
||||
handle = recorder_init(file, offset);
|
||||
}
|
||||
|
||||
public void start(){
|
||||
recorder_start( handle );
|
||||
}
|
||||
|
||||
|
||||
public void stop(){
|
||||
recorder_stop(handle);
|
||||
}
|
||||
|
||||
public long getCurrentOffset(){
|
||||
return recorder_getCurrentOffset(handle);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
System.loadLibrary("recorder");
|
||||
}
|
||||
|
||||
private native void recorder_start(int handle);
|
||||
|
||||
private native void recorder_stop(int handle );
|
||||
|
||||
private native int recorder_init(String file, long offset);
|
||||
|
||||
private native long recorder_getCurrentOffset(int handle);
|
||||
}
|
||||
373
Modules/sound/Sound.java
Normal file
373
Modules/sound/Sound.java
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
Sound.java
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
package org.gzigzag.module;
|
||||
import org.gzigzag.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Should be broken to smaller pieces.
|
||||
* @author Vesa Parkkinen <veparkki@iki.fi>
|
||||
*
|
||||
*/
|
||||
public class Sound {
|
||||
public static final String rcsid = "$Id: Sound.java,v 1.2 2001/03/27 20:43:25 tjl Exp $";
|
||||
|
||||
/* debugging */
|
||||
public static boolean dbg = true;
|
||||
static final void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
static final void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
/**
|
||||
* Static module used in gzigzag module loading.
|
||||
*/
|
||||
static public ZZModule module = new ZZModule() {
|
||||
public void action( String id, ZZCell code,
|
||||
ZZCell target,
|
||||
ZZView v, ZZView cv,
|
||||
String key, Point pt,
|
||||
ZZScene xi) {
|
||||
|
||||
p("Sound.module.action() " + id);
|
||||
if( id.equals("PLAY") ) {
|
||||
p("PLAYing...");
|
||||
instance.play(target);
|
||||
} else if( id.equals("RECORD")){
|
||||
p("RECORDing...");
|
||||
// what ehis should mean ?
|
||||
instance.record(target);
|
||||
} else if ( id.equals("STOP")) {
|
||||
p("STOPing...");
|
||||
instance.stop();
|
||||
} else if ( id.equals("CUT")){
|
||||
p("CUTing...");
|
||||
instance.cut();
|
||||
} else if ( id.equals("TAG")) {
|
||||
p("TAGing...");
|
||||
instance.tag(target);
|
||||
} else if ( id.equals("INIT")) {
|
||||
p("INITing...");
|
||||
instance.init(target);
|
||||
}
|
||||
}
|
||||
public ZOb newZOb(String id) {
|
||||
p("Sound.module.newZOb(" + id + ")");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
static String stream = "SNDSTR";
|
||||
static String file = "/tmp/soundscroll";
|
||||
|
||||
static String d = "d.sound";
|
||||
static String dtag = "d.handle";
|
||||
static String dspan = "d.sound-span";
|
||||
static String dsessions = "d.sound-sessions";
|
||||
|
||||
static long duration = 2000000;
|
||||
static String mod = "Sound";
|
||||
|
||||
static String[] ops = { //"INIT",
|
||||
"PLAY",
|
||||
"RECORD",
|
||||
"STOP",
|
||||
"CUT",
|
||||
"TAG"
|
||||
};
|
||||
|
||||
Recorder recorder = new SimpleRecorder();
|
||||
|
||||
public Span getSpan(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public ZZCell getSpanAsCell(){
|
||||
return null;
|
||||
}
|
||||
|
||||
//************************************************************************
|
||||
//* private variables
|
||||
//************************************************************************
|
||||
|
||||
private static Sound instance;
|
||||
|
||||
static {
|
||||
instance = new Sound();
|
||||
}
|
||||
|
||||
// current offset from the start of the session
|
||||
private long offset = 0;
|
||||
|
||||
// offset of the end of the last span
|
||||
private long lastOffset = 0;
|
||||
private long sessionStart = 0;
|
||||
|
||||
// are we playing at the moment
|
||||
private boolean playing = false;
|
||||
|
||||
// are we recording at the moment
|
||||
private boolean recording = false;
|
||||
|
||||
private Player player = null;
|
||||
|
||||
private ZZCell last = null;
|
||||
private ZZCell spanCell = null;
|
||||
private ZZCell sessionCell = null;
|
||||
|
||||
// THESE SHOULD COME FROM STRUCTURE
|
||||
|
||||
private SoundScroll soundScroll = null;
|
||||
// the session this stream belongs to
|
||||
private ZZCell session = null;
|
||||
// the input device associated with this stream.
|
||||
private ZZCell inDevice = null;
|
||||
// the input device associated with this stream.
|
||||
private ZZCell outDevice = null;
|
||||
|
||||
private ZZCell offsetCell = null;
|
||||
|
||||
public Sound(){
|
||||
//t.start();
|
||||
pa("CONSTRUCTOR!!!");
|
||||
}
|
||||
|
||||
ZZCell scrollCell = null;
|
||||
|
||||
private void init(ZZCell c){
|
||||
// TODO:
|
||||
// create a new window
|
||||
// with soundvie
|
||||
ZZDefaultSpace.addDimensionToDefaultDimlist(c, d);
|
||||
ZZDefaultSpace.addDimensionToDefaultDimlist(c, dspan);
|
||||
ZZDefaultSpace.addDimensionToDefaultDimlist(c, dsessions);
|
||||
ZZDefaultSpace.addDimensionToDefaultDimlist(c, "d.handle");
|
||||
//soundScroll = new SoundScroll(stream, file, 1000);
|
||||
//Scroll.register(stream, soundScroll);
|
||||
for(int i = 0; i < ops.length; i++){
|
||||
c = c.N("d.2", 1);
|
||||
c.setText(mod+"."+ops[i]);
|
||||
}
|
||||
addScroll(c);
|
||||
scrollCell = ZZDefaultSpace.findScrollCell(c.getHomeCell(), stream);
|
||||
soundScroll = (SoundScroll)Scroll.obtain( c.getSpace(),
|
||||
stream);
|
||||
if( spanCell != null )
|
||||
spanCell = scrollCell.N(dspan,1);
|
||||
|
||||
p("SOUNDSCROLL = " + soundScroll);
|
||||
}
|
||||
|
||||
private void addScroll(ZZCell c){
|
||||
if( c==null ) return;
|
||||
ZZCell home = c.getHomeCell();
|
||||
ZZCell d = home.findText("d.2", -1, "Scrolls");
|
||||
if( d == null ) {
|
||||
d = home.N("d.2",-1);
|
||||
d.setText("Scrolls");
|
||||
}
|
||||
ZZCell x = d.findText("d.1", 1, stream);
|
||||
if( x != null ) return ;
|
||||
d = d.N("d.1",1);
|
||||
d.setText(stream);
|
||||
d = d.N("d.2",1);
|
||||
d.setText(file);
|
||||
d = d.N("d.2",1);
|
||||
d.setText("Sound");
|
||||
d = d.N("d.2",1);
|
||||
d.setText("1000000");
|
||||
d = d.N("d.2",1);
|
||||
d.setText("offset");
|
||||
d = d.N("d.1",1);
|
||||
d.setText("0");
|
||||
offsetCell = d;
|
||||
}
|
||||
|
||||
|
||||
//************************************************************************
|
||||
//* public methods
|
||||
//************************************************************************
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void record(ZZCell session){
|
||||
if( playing || recording ) return;
|
||||
p("not recording or playing");
|
||||
// create a new scroll
|
||||
if( soundScroll == null )
|
||||
soundScroll = (SoundScroll)Scroll.obtain( session.getSpace(),
|
||||
stream);
|
||||
//file = soundScroll.getFile(file);
|
||||
|
||||
p("SOUNDSCROLL: " + soundScroll);
|
||||
|
||||
if( scrollCell == null ) {
|
||||
scrollCell = ZZDefaultSpace.findScrollCell(session.getHomeCell(),
|
||||
stream);
|
||||
}
|
||||
if( offsetCell == null) {
|
||||
pa("SCRCELL = " + scrollCell);
|
||||
offsetCell = scrollCell.findText("d.2", 1, "offset");
|
||||
offsetCell = offsetCell.s("d.1",1);
|
||||
}
|
||||
if( spanCell ==null ){
|
||||
spanCell = scrollCell.N(dspan,1);
|
||||
}
|
||||
if( sessionCell == null ){
|
||||
sessionCell = scrollCell.h(dsessions, 1);
|
||||
sessionCell = sessionCell.N(dsessions,1);
|
||||
}
|
||||
last = sessionCell;
|
||||
|
||||
final long scOffset = Long.parseLong(offsetCell.getText());
|
||||
offset = scOffset;
|
||||
p("are we recording yet... " + recording);
|
||||
p("initializing");
|
||||
// XXX chech the offset
|
||||
recorder.init("/tmp/soundscroll", scOffset);
|
||||
p("initalized...");
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
p("S REC Thread");
|
||||
recorder.start();
|
||||
offset = recorder.getCurrentOffset();
|
||||
p("offset = " + offset);
|
||||
offsetCell.setText(""+ offset);
|
||||
Span s = Span.create(
|
||||
Address.streamOffs(stream, 0),
|
||||
Address.streamOffs(stream, offset)
|
||||
);
|
||||
spanCell.setSpan(s);
|
||||
sessionCell.setSpan(s = Span.create(
|
||||
Address.streamOffs(stream, scOffset),
|
||||
Address.streamOffs(stream, offset)
|
||||
));
|
||||
last.setSpan(s);
|
||||
lastOffset = offset;
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
last = last.N(d,1);
|
||||
recording = true;
|
||||
}
|
||||
|
||||
public void play(){
|
||||
play(0);
|
||||
}
|
||||
|
||||
public void play(long off){
|
||||
if( ! (playing || recording )) ; // start to play
|
||||
}
|
||||
|
||||
public void play(ZZCell from ){
|
||||
p("play " + from);
|
||||
|
||||
Span s = from.getSpan();
|
||||
if( s == null ) {
|
||||
pa("Not a span cell!!!");
|
||||
return;
|
||||
}
|
||||
if( soundScroll == null )
|
||||
soundScroll = (SoundScroll)s.getStart().getScroll(from.getSpace());
|
||||
// get these from factory???
|
||||
player = new SimplePlayer();
|
||||
File f = soundScroll.getFile();
|
||||
p("FILE = " + f);
|
||||
p("FILE = " + f.toString());
|
||||
player.init(f.toString());
|
||||
p("initialized...\n");
|
||||
final ZZCell fc = from;
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
p("PlayerThread");
|
||||
player.play(fc.getSpan().getStart().getOffs(),
|
||||
fc.getSpan().getEnd().getOffs(), false);
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
playing = true;
|
||||
|
||||
}
|
||||
|
||||
public void play(ZZCell from, Dimension d, int dir ){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new span cell from last cut to this cut and connect
|
||||
* new cell to the stream cells.
|
||||
*/
|
||||
public void cut(){
|
||||
offset = recorder.getCurrentOffset();
|
||||
p("offset = " + offset);
|
||||
Span s = Span.create(
|
||||
Address.streamOffs(stream, lastOffset),
|
||||
Address.streamOffs(stream, offset)
|
||||
);
|
||||
p("SPAN = " +s );
|
||||
p("span.getText(): " + s.getString(last));
|
||||
|
||||
last.setSpan(s);
|
||||
lastOffset = offset;
|
||||
last = last.N(d,1);
|
||||
}
|
||||
|
||||
public void tag(ZZCell t){
|
||||
p( "target: " + t);
|
||||
last.insert(dtag,1, t);
|
||||
}
|
||||
|
||||
|
||||
public void pause(){
|
||||
if( playing ){
|
||||
player.stop();
|
||||
playing = false;
|
||||
return ;
|
||||
}
|
||||
|
||||
if( recording ){
|
||||
player.stop();
|
||||
recording = false;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if( playing ){
|
||||
player.stop();
|
||||
p("player stopped\n");
|
||||
playing = false;
|
||||
return ;
|
||||
}
|
||||
|
||||
if( recording ){
|
||||
p("stopping recorder...");
|
||||
recorder.stop();
|
||||
recording = false;
|
||||
p("recorder stopped\n");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
2
Modules/sound/gsm_def.h
Normal file
2
Modules/sound/gsm_def.h
Normal file
@@ -0,0 +1,2 @@
|
||||
#define GSM_SAMPLE 160 * 2
|
||||
#define GSM_FRAME 33 * 2
|
||||
247
Modules/sound/gsm_player.c
Normal file
247
Modules/sound/gsm_player.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
gsm_player.c
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************
|
||||
* INCLUDES
|
||||
****************************************************/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <gsm/gsm.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "org_gzigzag_module_SimplePlayer.h"
|
||||
#include "gsm_def.h"
|
||||
|
||||
/****************************************************
|
||||
* DEFINES
|
||||
****************************************************/
|
||||
#define DEVICE "/dev/dsp"
|
||||
#define DEFAULT_DSP_SPEED 8000
|
||||
#define DEFAULT_DSP_FRAG 0
|
||||
#define DEFAULT_DSP_SAMPLE
|
||||
#define PLAYS 10
|
||||
|
||||
|
||||
#ifndef uint
|
||||
#define uint unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef ulong
|
||||
#define ulong unsigned long
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_SOUND
|
||||
#define DEBUG_SOUND 0
|
||||
#endif
|
||||
#define DEBUG(s) if(DEBUG_SOUND)printf(s);
|
||||
|
||||
/****************************************************
|
||||
* STRUCTS
|
||||
****************************************************/
|
||||
/**
|
||||
* playing
|
||||
* Struct to hold infomation about playing.
|
||||
*/
|
||||
typedef struct {
|
||||
char *file; // file to read from
|
||||
int audio; // handle to audio device
|
||||
int speed;
|
||||
int samplesize;
|
||||
int fragsize;
|
||||
int channels; // mono 1, stereo 2
|
||||
long offset; // bytes from beginning
|
||||
int stop;
|
||||
int format;
|
||||
} Playing;
|
||||
|
||||
|
||||
Playing *pls[PLAYS];
|
||||
|
||||
int cur_play = 0;
|
||||
|
||||
/**
|
||||
* Error handling
|
||||
*/
|
||||
void per(char *str){
|
||||
printf("** player error: %s\n", str);
|
||||
perror("ERROR: " );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new playing structure, and increments
|
||||
* curr_play by 1.
|
||||
* @return a pointer to new Playing struvct or NULL
|
||||
*/
|
||||
Playing *new_playing(int *rn){
|
||||
Playing *r = (Playing *) malloc(sizeof(Playing));
|
||||
cur_play++;
|
||||
pls[cur_play] = r;
|
||||
*rn = cur_play;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int init_playing(Playing *rec){
|
||||
rec->file = "/tmp/soundscroll";
|
||||
rec->audio = 0;
|
||||
rec->speed = 8000;
|
||||
rec->samplesize = 8;
|
||||
rec->fragsize = 0; // not used at the moment
|
||||
rec->channels = 1;
|
||||
rec->offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the recording device.
|
||||
*/
|
||||
int init_playing_device(const char *file){
|
||||
|
||||
int rn = 0;
|
||||
Playing *r = new_playing(&rn);
|
||||
init_playing(r);
|
||||
r->file = strdup(file);
|
||||
r->stop = -1;
|
||||
r->offset = 0;
|
||||
DEBUG("init device\n");
|
||||
|
||||
if ( (r->audio = open(DEVICE, O_WRONLY) ) < 0 ) {
|
||||
per("OPEN FAILED");
|
||||
return 0;
|
||||
}
|
||||
DEBUG("opened device\n");
|
||||
|
||||
ioctl(r->audio, SNDCTL_DSP_SAMPLESIZE, &r->samplesize);
|
||||
|
||||
if ( ioctl(r->audio, SNDCTL_DSP_SETFMT,
|
||||
&r->format) == -1 ) {
|
||||
perror("ioctl format");
|
||||
}
|
||||
|
||||
if (ioctl (r->audio, SNDCTL_DSP_SPEED, &r->speed) == -1){
|
||||
per("set speed failed");
|
||||
}
|
||||
|
||||
if (ioctl(r->audio, SNDCTL_DSP_CHANNELS, &r->channels) == -1) {
|
||||
per("SNDCTL_DSP_CHANNELS");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rn;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* INIT *
|
||||
*******************************************************************/
|
||||
JNIEXPORT jint JNICALL Java_org_gzigzag_module_SimplePlayer_player_1init
|
||||
(JNIEnv *env, jobject obj, jstring file){
|
||||
int rv=0;
|
||||
const char *fn = (const char *)(*env)->GetStringUTFChars(env, file, 0);
|
||||
rv = init_playing_device(fn);
|
||||
(*env)->ReleaseStringUTFChars(env, file, fn);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* STOP *
|
||||
*******************************************************************/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimplePlayer_player_1stop
|
||||
(JNIEnv *env, jobject obj, jint handle){
|
||||
Playing *r = pls[handle];
|
||||
if ( r == NULL) return ;
|
||||
DEBUG("native STOP\n");
|
||||
r->stop = 1;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* START *
|
||||
*******************************************************************/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimplePlayer_player_1start
|
||||
(JNIEnv *env, jobject obj, jint handle, jlong from, jlong to){
|
||||
int fd = 0;
|
||||
gsm_frame buf;
|
||||
long f = from;
|
||||
long t = to;
|
||||
int g=0;
|
||||
int i;
|
||||
Playing *r = pls[handle];
|
||||
unsigned char accbuf[160];
|
||||
gsm gsm = gsm_create();
|
||||
gsm_signal gsm_out[160];
|
||||
|
||||
DEBUG("starting...\n");
|
||||
|
||||
if ((fd = open (r->file, O_RDONLY)) == -1){
|
||||
per("open failed");
|
||||
return;
|
||||
}
|
||||
|
||||
lseek(fd, f, SEEK_SET);
|
||||
printf("to= %ld\n", t);
|
||||
r->offset = f;
|
||||
while (r->stop < 1 && r->offset < t){
|
||||
if (read (fd, (char *)buf, sizeof(buf)) != sizeof(buf)){
|
||||
per("read failed");
|
||||
close(fd);
|
||||
close(r->audio);
|
||||
return;
|
||||
}
|
||||
|
||||
if( gsm_decode(gsm, buf, gsm_out) < 0){
|
||||
perror("error decoding...");
|
||||
return ;
|
||||
}
|
||||
|
||||
for(g=0;g<160;g++){
|
||||
i=(int)gsm_out[g]+32768;
|
||||
i>>=8;
|
||||
/*gsm_out[g]=(unsigned char)i;*/
|
||||
accbuf[g]=(unsigned char)i;
|
||||
}
|
||||
|
||||
if ( (write (r->audio, accbuf, sizeof(accbuf))) != sizeof(accbuf)){
|
||||
per("write failed");
|
||||
close(fd);
|
||||
close(r->audio);
|
||||
return;
|
||||
}
|
||||
r->offset += sizeof(buf);
|
||||
} /* While */
|
||||
|
||||
if (fd != 1)
|
||||
close (fd);
|
||||
|
||||
close( r->audio );
|
||||
|
||||
DEBUG("played\n");
|
||||
}
|
||||
240
Modules/sound/gsm_recorder.c
Normal file
240
Modules/sound/gsm_recorder.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
gsm_recorder.c
|
||||
*
|
||||
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software 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 README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Vesa Parkkinen
|
||||
*/
|
||||
/**
|
||||
* simple gsm recorder
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************
|
||||
* INCLUDES
|
||||
****************************************************/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <gsm/gsm.h>
|
||||
|
||||
#include "jni.h"
|
||||
#include "org_gzigzag_module_SimpleRecorder.h"
|
||||
#include "gsm_def.h"
|
||||
|
||||
/****************************************************
|
||||
* DEFINES
|
||||
****************************************************/
|
||||
#define DEVICE "/dev/dsp"
|
||||
#define DEFAULT_DSP_SPEED 8000
|
||||
#define DEFAULT_DSP_FRAG 0
|
||||
#define DEFAULT_DSP_SAMPLE
|
||||
#define RECS 10
|
||||
#define READ_BLOCK 1280
|
||||
#define BUFFER_SIZE 20 * READ_BLOCK
|
||||
#define GSM_RECORDER_DEBUG 1
|
||||
//#define ENCODED_SIZE 20 * READ_BLOCK
|
||||
|
||||
#ifndef uint
|
||||
#define uint unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef ulong
|
||||
#define ulong unsigned long
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_SOUND
|
||||
#define DEBUG_SOUND 0
|
||||
#endif
|
||||
|
||||
#define DEBUG(s) if(DEBUG_SOUND)printf(s);
|
||||
/****************************************************
|
||||
* STRUCTS
|
||||
****************************************************/
|
||||
|
||||
/**
|
||||
* Recording
|
||||
* Struct to hold infomation about recordings.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
char *file; // file to save to
|
||||
int audio; // handle to audio device
|
||||
int speed;
|
||||
int samplesize;
|
||||
int fragsize;
|
||||
int channels; // mono 1, stereo 2
|
||||
ulong offset; // bytes from beginning
|
||||
int format;
|
||||
int stop;
|
||||
|
||||
} Recording;
|
||||
|
||||
Recording *recs[RECS];
|
||||
int cur_rec = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int init_recording(Recording *rec){
|
||||
rec->file = "/tmp/sndscroll";
|
||||
rec->audio = 0;
|
||||
rec->speed = 8000;
|
||||
rec->samplesize = 8;
|
||||
rec->fragsize = 0; // not used at the moment
|
||||
rec->channels = 1;
|
||||
rec->offset = 0;
|
||||
rec->stop = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new recording structure, and increments
|
||||
* curr_rec by 1.
|
||||
* @return a pointer to new Recording struvct or NULL
|
||||
*/
|
||||
Recording *new_recording(int *rn){
|
||||
Recording *r = (Recording *) malloc(sizeof(Recording));
|
||||
cur_rec++;
|
||||
recs[cur_rec] = r;
|
||||
*rn = cur_rec;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the recording device.
|
||||
*/
|
||||
int init_device(const char *file){
|
||||
int rn = 0;
|
||||
Recording *r = new_recording(&rn);
|
||||
init_recording(r);
|
||||
r->file = strdup(file);
|
||||
r->stop = -1;
|
||||
|
||||
DEBUG("init device\n");
|
||||
|
||||
if ( (r->audio = open(DEVICE, O_RDONLY) ) < 0 ) {
|
||||
perror("OPEN FAILED");
|
||||
}
|
||||
|
||||
DEBUG("opened device\n");
|
||||
|
||||
if( ioctl(r->audio, SNDCTL_DSP_SAMPLESIZE, &r->samplesize) == -1){
|
||||
perror("SNDCTL_DSP_SAMPLESIZE");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(r->audio, SNDCTL_DSP_CHANNELS, &r->channels) == -1) {
|
||||
perror("SNDCTL_DSP_CHANNELS");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl (r->audio, SNDCTL_DSP_SPEED, &r->speed) == -1){
|
||||
perror("set speed failed");
|
||||
}
|
||||
DEBUG("initialized device\n");
|
||||
return rn;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* GET CURRENT OFFSET *
|
||||
*******************************************************************/
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_org_gzigzag_module_SimpleRecorder_recorder_1getCurrentOffset
|
||||
(JNIEnv *env, jobject obj , jint handle){
|
||||
Recording *r = recs[handle];
|
||||
if( r == NULL ) return 0;
|
||||
return r->offset;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* INIT *
|
||||
*******************************************************************/
|
||||
JNIEXPORT jint JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1init
|
||||
(JNIEnv *env, jobject obj, jstring file, jlong offset){
|
||||
int rv=0;
|
||||
const char *fn = (const char *)(*env)->GetStringUTFChars(env, file, 0);
|
||||
rv = init_device(fn);
|
||||
(*env)->ReleaseStringUTFChars(env, file, fn);
|
||||
recs[rv]->offset = offset;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* STOP *
|
||||
*******************************************************************/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1stop
|
||||
(JNIEnv *env, jobject obj, jint handle){
|
||||
Recording *r = recs[handle];
|
||||
if ( r == NULL) return ;
|
||||
r->stop = 1;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* START *
|
||||
*******************************************************************/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1start
|
||||
(JNIEnv *env, jobject obj, jint handle){
|
||||
|
||||
int fd = 0;
|
||||
char *audiobuf;
|
||||
|
||||
gsm gsm = gsm_create();
|
||||
gsm_signal sample[160];
|
||||
gsm_frame frame;
|
||||
|
||||
Recording *r = recs[handle];
|
||||
|
||||
if ((fd = open (r->file, O_WRONLY | O_CREAT, 0666)) == -1){
|
||||
perror("recorder start: open failed");
|
||||
return ;
|
||||
}
|
||||
|
||||
lseek(fd, r->offset, SEEK_SET);
|
||||
|
||||
while ( r->stop < 1 ){
|
||||
read (r->audio, sample, sizeof(sample) );
|
||||
gsm_encode(gsm, sample, frame);
|
||||
|
||||
// write
|
||||
if (write (fd, frame, sizeof(frame)) != sizeof(frame)){
|
||||
perror("write failed");
|
||||
//exit (-1);
|
||||
return ;
|
||||
}
|
||||
r->offset += sizeof(frame);
|
||||
}
|
||||
if (fd != 1)
|
||||
close (fd);
|
||||
|
||||
close( r->audio );
|
||||
|
||||
gsm_destroy(gsm);
|
||||
|
||||
printf("recorded\n");
|
||||
}
|
||||
45
Modules/sound/org_gzigzag_module_SimplePlayer.h
Normal file
45
Modules/sound/org_gzigzag_module_SimplePlayer.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_gzigzag_module_SimplePlayer */
|
||||
|
||||
#ifndef _Included_org_gzigzag_module_SimplePlayer
|
||||
#define _Included_org_gzigzag_module_SimplePlayer
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimplePlayer
|
||||
* Method: player_init
|
||||
* Signature: (Ljava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_gzigzag_module_SimplePlayer_player_1init
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimplePlayer
|
||||
* Method: player_start
|
||||
* Signature: (IJJ)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimplePlayer_player_1start
|
||||
(JNIEnv *, jobject, jint, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimplePlayer
|
||||
* Method: player_getCurrentOffset
|
||||
* Signature: (I)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_gzigzag_module_SimplePlayer_player_1getCurrentOffset
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimplePlayer
|
||||
* Method: player_stop
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimplePlayer_player_1stop
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
45
Modules/sound/org_gzigzag_module_SimpleRecorder.h
Normal file
45
Modules/sound/org_gzigzag_module_SimpleRecorder.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class org_gzigzag_module_SimpleRecorder */
|
||||
|
||||
#ifndef _Included_org_gzigzag_module_SimpleRecorder
|
||||
#define _Included_org_gzigzag_module_SimpleRecorder
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimpleRecorder
|
||||
* Method: recorder_start
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1start
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimpleRecorder
|
||||
* Method: recorder_stop
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1stop
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimpleRecorder
|
||||
* Method: recorder_init
|
||||
* Signature: (Ljava/lang/String;J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1init
|
||||
(JNIEnv *, jobject, jstring, jlong);
|
||||
|
||||
/*
|
||||
* Class: org_gzigzag_module_SimpleRecorder
|
||||
* Method: recorder_getCurrentOffset
|
||||
* Signature: (I)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_org_gzigzag_module_SimpleRecorder_recorder_1getCurrentOffset
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user