Commit 7803c731 authored by daFischer's avatar daFischer

Audio now uses Html5 audio tag

parent 9df8d57b
emBuild/TTT/
\ No newline at end of file
......@@ -2,45 +2,37 @@
* File: Audio.cpp
* Author: user
* http://wiki.delphigl.com/index.php/OpenAL-Funktions%C3%BCbersicht
* http://www.codeproject.com/Articles/656543/The-LAME-wrapper-An-audio-converter
* https://github.com/sopel39/audioconverter.js
* Created on April 30, 2014, 3:39 PM
*/
#include "Audio.h"
ALbyte Audio::fileBuffer[100000];
Audio::Audio(const char* path) {
//settings
playing=0;
failed=true;
int error;
struct stat statbuf;
if(!(device = alcOpenDevice(NULL)))
{
printf("no device\n");
return;
}
if(!(context = alcCreateContext(device, NULL)))
{
printf("no context\n");
return;
}
if(!alcMakeContextCurrent(context))
{
printf("no current\n");
return;
}
if((error = alcGetError(device)) != ALC_NO_ERROR)
int n=0;
char c=0;
char* cc=&c;
alutInit(&n,&cc);
if((error=alutGetError()) != ALUT_ERROR_NO_ERROR)
{
printf("alc error: %d\n", error);
printf("Error0 (Audio): %d\n",error);
return;
}
alGenBuffers(1, &buffer); //Generate buffer
alGenSources(1, &source); //Generate source
if(alGetError() != AL_NO_ERROR)
if((error=alGetError()) != AL_NO_ERROR)
{
printf("Error (Audio)\n");
printf("Error2 (Audio): %d\n",error);
return;
}
//Load our audio file from disk
......@@ -51,17 +43,16 @@ Audio::Audio(const char* path) {
for(int i=0;i<sizeof(extension);i++) //try loading audio of all possible extensions
{
filename=path+extension[i];
if(readAudio(filename.c_str(),extension[i]))
{
printf("loaded %s\n",filename.c_str());
buffer=alutCreateBufferFromFile(filename.c_str());
if((error=alutGetError())==ALUT_ERROR_NO_ERROR)
break;
}
printf("Couldn't load %s: %d\n",filename.c_str(),error);
if(i == sizeof(extension) -1)
{
alDeleteBuffers(1, &buffer);
}
}
//alBufferData(buffer,format,data,size,frequency); //fill buffer with audio data
alSourcei (source, AL_BUFFER, buffer);
if (alGetError() != AL_NO_ERROR)
......@@ -75,87 +66,28 @@ Audio::Audio(const char* path) {
void Audio::play(){
//Play the audio file
printf("play1\n");
alSourcePlay(source);
printf("play2\n");
printf("Start playing for %d ms\n",getDuration());
/*if(Mix_PlayMusic(audio, 0) == -1)
{
printf("Unable to play audio file: %s\n", Mix_GetError());
return;
}*/
//The audio is playing!
playing = 1;
//startTime=0;
/*printf("Setting time\n");
if(setPosition(30)==0)
printf("Unable to set Position\n");*/
//Make sure that the finished() function is called when the audio stops playing
//Mix_HookMusicFinished(audioFinished);
}
bool Audio::readAudio(const char* path, string type){
struct stat statbuf;
if(stat(path, &statbuf) != 0 || !S_ISREG(statbuf.st_mode))
{
printf("No %s file found.\n", type.c_str());
continue;
}
int error;
switch(type)
{
case ".mp3":
return false;
break;
case ".mp2":
return false;
break;
case ".ogg":
return false;
break;
case ".wav":
FILE* f = fopen (path , "r");
alBufferData(buffer,format,data,size,freq);
if((error = alGetError()) != AL_NO_ERROR)
{
printf("No %s file loaded: %d\n", type.c_str(), error);
continue;
}
break;
}
}
/*static void audioFinished()
{
printf("Finished the Audio\n");
}
void Audio::finished()
{
//Audio is done!
printf("Finished the Audio2\n");
playing = 0;
}*/
int Audio::getTime()
int Audio::getPosition()
{
ALfloat time;
alGetSourcef(source, AL_SEC_OFFSET, &time);
if(alGetError()!= AL_NO_ERROR)
printf("getTime error\n");
int error;
if((error = alGetError())!= AL_NO_ERROR)
printf("getTime error: %d\n", error);
//printf("%f\n",(float) time);
return (int)(time*1000);
}
bool Audio::setPosition(int time)
/*bool Audio::setPosition(int time)
{
ALfloat pos=(ALfloat)pos/1000.0;
alSourcef(source, AL_SEC_OFFSET, pos);
......@@ -163,7 +95,7 @@ bool Audio::setPosition(int time)
return true;
else
return false;
}
}*/
int Audio::getDuration()
{
......@@ -187,3 +119,8 @@ int Audio::getDuration()
return (int)(seconds*1000);
}
bool Audio::hasFailed()
{
return failed;
}
......@@ -14,44 +14,36 @@
#include <sys/stat.h>
#include <AL/al.h>
#ifdef EMSCRIPTEN
#include "alut.h"
#else
#include <AL/alut.h>
#endif
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>
#define BUFFER_SIZE 4096
#include "AudioInterface.h"
#define BUFFER_SIZE 100000
using namespace std;
static void audioFinished();
//static void audioFinished();
class Audio {
class Audio: public AudioInterface{
public:
Audio(const char*);
void play();
void finished();
int getTime();
bool setPosition(int time);
int getPosition();
//bool setPosition(int time);
int getDuration();
bool hasFailed();
bool failed;
private:
bool readAudio(const char* path, string type);
bool failed;
ALuint source;
ALuint buffer;
ALCdevice *device;
ALCcontext *context;
//ALsizei size;
//ALsizei frequency; //Frequency of audio playback
//ALenum format; //Format of the audio we're playing
//ALvoid* data;
//unsigned char *buf;
//int pid;
//int files[2];
//FILE *f;
int playing;
//int startTime;
//int currentTime;
static ALbyte fileBuffer[100000];
};
#endif /* AUDIO_H */
......
/*
* File: AudioInterface.cpp
* Author: user
*
* Created on July 13, 2014, 2:15 PM
*/
#include "AudioInterface.h"
AudioInterface::AudioInterface(){
}
void AudioInterface::play(){
}
int AudioInterface::getDuration(){
return 0;
}
int AudioInterface::getPosition(){
return 0;
}
bool AudioInterface::hasFailed(){
return true;
}
/*
* File: AudioInterface.h
* Author: user
*
* Created on July 13, 2014, 2:15 PM
*/
#ifndef AUDIOINTERFACE_H
#define AUDIOINTERFACE_H
#include <stdio.h>
using namespace std;
class AudioInterface {
public:
AudioInterface();
virtual void play();
virtual int getPosition();
virtual int getDuration();
virtual bool hasFailed();
};
#endif /* AUDIOINTERFACE_H */
/*
* File: AudioJS.cpp
* Author: user
*
* Created on July 13, 2014, 2:51 PM
*/
#ifdef EMSCRIPTEN
#include "AudioJS.h"
AudioJS::AudioJS() {
duration = EM_ASM_INT({
return x_getDuration();
},0);
printf("Duration: %d min\n",duration/60000);
}
void AudioJS::play(){
EM_ASM(
x_play();
);
}
int AudioJS::getDuration(){
return duration;
}
int AudioJS::getPosition(){
return EM_ASM_INT({
return x_getPosition();
},0);
}
bool AudioJS::hasFailed(){
return false;
}
#endif
/*
* File: AudioJS.h
* Author: user
*
* Created on July 13, 2014, 2:51 PM
*/
#ifndef EMSCRIPTEN
#define AUDIOJS_H
#endif /* EMSCRIPTEN */
#ifndef AUDIOJS_H
#define AUDIOJS_H
#include <emscripten/emscripten.h>
#include <stdio.h>
#include "AudioInterface.h"
using namespace std;
class AudioJS: public AudioInterface{
public:
AudioJS();
void play();
int getPosition();
int getDuration();
bool hasFailed();
private:
int duration;
};
#endif /* AUDIOJS_H */
......@@ -6,6 +6,7 @@
*/
#include "Player.h"
#include "AudioJS.h"
Player *player;
......@@ -25,12 +26,16 @@ Player::Player(const char* cpath, const char* cfilename) {
std::string filename=cfilename;
std::string path=cpath;
audio=new Audio((path+"/"+filename+"_a/"+filename).c_str());
video=new Video((path+"/"+filename+"_a/"+filename+".ttt").c_str());
#ifdef EMSCRIPTEN
audio=new AudioJS();
#else
audio=new Audio((path+"/"+filename+"_a/"+filename).c_str());
#endif
if(video->failed||audio->failed)
if(video->failed||audio->hasFailed())
{
printf("Audio failed: %s\nVideo failed: %s\n",audio->failed ? "true" : "false",video->failed ? "true" : "false");
printf("Audio failed: %s\nVideo failed: %s\n",audio->hasFailed() ? "true" : "false",video->failed ? "true" : "false");
return;
}
......@@ -54,7 +59,7 @@ Player::Player(const char* cpath, const char* cfilename) {
void Player::loop()
{
video->update(audio->getTime());
video->update(audio->getPosition());
SDL_Event event;
while (SDL_PollEvent(&event))
......
......@@ -20,7 +20,12 @@
#include <fstream>
#include <time.h>
#include "AudioInterface.h"
#ifdef EMSCRIPTEN
#include "AudioJS.h"
#else
#include "Audio.h"
#endif
#include "Video.h"
using namespace std;
......@@ -32,9 +37,10 @@ public:
virtual ~Player();
private:
Audio *audio;
AudioInterface *audio;
Video *video;
bool paused;
const char* filename;
#ifndef EMSCRIPTEN
bool quit;
#endif
......
#if !defined(AL_ALUT_H)
#define AL_ALUT_H
#if defined(_MSC_VER)
#include <alc.h>
#include <al.h>
#elif defined(__APPLE__)
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
#if defined(__cplusplus)
extern "C"
{
#endif
#if defined(_WIN32) && !defined(_XBOX)
#if defined (ALUT_BUILD_LIBRARY)
#define ALUT_API __declspec(dllexport)
#else
#define ALUT_API __declspec(dllimport)
#endif
#else
#if defined(ALUT_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define ALUT_API __attribute__((visibility("default")))
#else
#define ALUT_API extern
#endif
#endif
#if defined(_WIN32)
#define ALUT_APIENTRY __cdecl
#else
#define ALUT_APIENTRY
#endif
#if defined(__MWERKS_)
#pragma export on
#endif
/* Flag deprecated functions if possible (VisualC++ .NET and GCC >= 3.1.1). */
#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(MIDL_PASS)
#define ALUT_ATTRIBUTE_DEPRECATED __declspec(deprecated)
#elif defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && (__GNUC_MINOR__ > 1 || (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 1))))
#define ALUT_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#else
#define ALUT_ATTRIBUTE_DEPRECATED
#endif
#define ALUT_API_MAJOR_VERSION 1
#define ALUT_API_MINOR_VERSION 1
#define ALUT_ERROR_NO_ERROR 0
#define ALUT_ERROR_OUT_OF_MEMORY 0x200
#define ALUT_ERROR_INVALID_ENUM 0x201
#define ALUT_ERROR_INVALID_VALUE 0x202
#define ALUT_ERROR_INVALID_OPERATION 0x203
#define ALUT_ERROR_NO_CURRENT_CONTEXT 0x204
#define ALUT_ERROR_AL_ERROR_ON_ENTRY 0x205
#define ALUT_ERROR_ALC_ERROR_ON_ENTRY 0x206
#define ALUT_ERROR_OPEN_DEVICE 0x207
#define ALUT_ERROR_CLOSE_DEVICE 0x208
#define ALUT_ERROR_CREATE_CONTEXT 0x209
#define ALUT_ERROR_MAKE_CONTEXT_CURRENT 0x20A
#define ALUT_ERROR_DESTROY_CONTEXT 0x20B
#define ALUT_ERROR_GEN_BUFFERS 0x20C
#define ALUT_ERROR_BUFFER_DATA 0x20D
#define ALUT_ERROR_IO_ERROR 0x20E
#define ALUT_ERROR_UNSUPPORTED_FILE_TYPE 0x20F
#define ALUT_ERROR_UNSUPPORTED_FILE_SUBTYPE 0x210
#define ALUT_ERROR_CORRUPT_OR_TRUNCATED_DATA 0x211
#define ALUT_WAVEFORM_SINE 0x100
#define ALUT_WAVEFORM_SQUARE 0x101
#define ALUT_WAVEFORM_SAWTOOTH 0x102
#define ALUT_WAVEFORM_WHITENOISE 0x103
#define ALUT_WAVEFORM_IMPULSE 0x104
#define ALUT_LOADER_BUFFER 0x300
#define ALUT_LOADER_MEMORY 0x301
ALUT_API ALboolean ALUT_APIENTRY alutInit(int *argcp, char **argv);
ALUT_API ALboolean ALUT_APIENTRY alutInitWithoutContext(int *argcp, char **argv);
ALUT_API ALboolean ALUT_APIENTRY alutExit(void);
ALUT_API ALenum ALUT_APIENTRY alutGetError(void);
ALUT_API const char *ALUT_APIENTRY alutGetErrorString(ALenum error);
ALUT_API ALuint ALUT_APIENTRY alutCreateBufferFromFile(const char *fileName);
ALUT_API ALuint ALUT_APIENTRY alutCreateBufferFromFileImage(const ALvoid * data, ALsizei length);
ALUT_API ALuint ALUT_APIENTRY alutCreateBufferHelloWorld(void);
ALUT_API ALuint ALUT_APIENTRY alutCreateBufferWaveform(ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration);
ALUT_API ALvoid *ALUT_APIENTRY alutLoadMemoryFromFile(const char *fileName, ALenum * format, ALsizei * size, ALfloat * frequency);
ALUT_API ALvoid *ALUT_APIENTRY alutLoadMemoryFromFileImage(const ALvoid * data, ALsizei length, ALenum * format, ALsizei * size,
ALfloat * frequency);
ALUT_API ALvoid *ALUT_APIENTRY alutLoadMemoryHelloWorld(ALenum * format, ALsizei * size, ALfloat * frequency);
ALUT_API ALvoid *ALUT_APIENTRY alutLoadMemoryWaveform(ALenum waveshape, ALfloat frequency, ALfloat phase, ALfloat duration, ALenum * format,
ALsizei * size, ALfloat * freq);
ALUT_API const char *ALUT_APIENTRY alutGetMIMETypes(ALenum loader);
ALUT_API ALint ALUT_APIENTRY alutGetMajorVersion(void);
ALUT_API ALint ALUT_APIENTRY alutGetMinorVersion(void);
ALUT_API ALboolean ALUT_APIENTRY alutSleep(ALfloat duration);
/* Nasty Compatibility stuff, WARNING: THESE FUNCTIONS ARE STRONGLY DEPRECATED */
#if defined(__APPLE__)
ALUT_API ALUT_ATTRIBUTE_DEPRECATED void ALUT_APIENTRY alutLoadWAVFile(ALbyte * fileName, ALenum * format, void **data, ALsizei * size,
ALsizei * frequency);
ALUT_API ALUT_ATTRIBUTE_DEPRECATED void ALUT_APIENTRY alutLoadWAVMemory(ALbyte * buffer, ALenum * format, void **data, ALsizei * size,
ALsizei * frequency);
#else
ALUT_API ALUT_ATTRIBUTE_DEPRECATED void ALUT_APIENTRY alutLoadWAVFile(ALbyte * fileName, ALenum * format, void **data, ALsizei * size,
ALsizei * frequency, ALboolean * loop);
ALUT_API ALUT_ATTRIBUTE_DEPRECATED void ALUT_APIENTRY alutLoadWAVMemory(ALbyte * buffer, ALenum * format, void **data, ALsizei * size,
ALsizei * frequency, ALboolean * loop);
#endif
ALUT_API ALUT_ATTRIBUTE_DEPRECATED void ALUT_APIENTRY alutUnloadWAV(ALenum format, ALvoid * data, ALsizei size, ALsizei frequency);
#if defined(__MWERKS_)
#pragma export off
#endif
#if defined(__cplusplus)
}
#endif
#endif
build/Debug/GNU-Linux-x86/Audio.o: Audio.cpp Audio.h
build/Debug/GNU-Linux-x86/Audio.o: Audio.cpp Audio.h AudioInterface.h
Audio.h:
AudioInterface.h:
build/Debug/GNU-Linux-x86/AudioInterface.o: AudioInterface.cpp \
AudioInterface.h
AudioInterface.h:
build/Debug/GNU-Linux-x86/AudioJS.o: AudioJS.cpp
build/Debug/GNU-Linux-x86/Player.o: Player.cpp Player.h Audio.h Video.h \
Inflater.h SizedArray.h ProtocolPreferences.h Message.h Constants.h
build/Debug/GNU-Linux-x86/Player.o: Player.cpp Player.h AudioInterface.h \
Audio.h Video.h Inflater.h SizedArray.h ProtocolPreferences.h Message.h \
Constants.h AudioJS.h
Player.h:
AudioInterface.h:
Audio.h:
Video.h:
......@@ -16,3 +19,5 @@ ProtocolPreferences.h:
Message.h:
Constants.h:
AudioJS.h:
build/Debug/GNU-Linux-x86/main.o: main.cpp main.h Player.h Audio.h \
Video.h Inflater.h SizedArray.h ProtocolPreferences.h Message.h \
Constants.h
build/Debug/GNU-Linux-x86/main.o: main.cpp main.h Player.h \
AudioInterface.h Audio.h Video.h Inflater.h SizedArray.h \
ProtocolPreferences.h Message.h Constants.h
main.h:
Player.h:
AudioInterface.h:
Audio.h:
Video.h:
......
var x_audio=document.getElementById('audioplayer');
var x_seeked=false;
var x_getSeek=function(){
if(x_seeked)
{
x_seeked=false;
return true;
}
return false;
}
var x_getPosition=function(){
return x_audio.currentTime*1000;
}
var x_getDuration=function(){
return x_audio.duration*1000;
}
var x_play=function(){
x_audio.play();
}
var x_audioLoaded=function(){
}
/*var x_setPosition=function(pos){
x_audio.currentTime=pos/1000;
}*/
<audio id ="audioplayer" onloadeddata="x_audioLoaded()" onseeking="x_seeked=true;" controls>
<source src="TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.ogg" type="audio/ogg">
<source src="TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.mp3" type="audio/mp3">
<source src="TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.wav" type="audio/wav">
Your browser does not support the audio element.
</audio>
<script type="text/javascript" src="Audio.js"></script>
......@@ -6,21 +6,21 @@ DIR=../
MESSAGES= $(DIR)DeleteAllAnnotation.cpp $(DIR)EmptyMessage.cpp $(DIR)HextileMessage.cpp $(DIR)Message.cpp $(DIR)WhiteboardMessage.cpp
ZSRC = libz/adler32.c libz/compress.c libz/crc32.c libz/deflate.c libz/gzclose.c libz/gzlib.c libz/gzread.c \
libz/gzwrite.c libz/infback.c libz/inffast.c libz/inflate.c libz/inftrees.c libz/trees.c libz/uncompr.c libz/zutil.c
SRC= $(DIR)Audio.cpp $(DIR)ColorConverter.cpp $(DIR)Constants.cpp $(DIR)Inflater.cpp $(DIR)Player.cpp $(DIR)ProtocolPreferences.cpp $(DIR)SizedArray.cpp $(DIR)Video.cpp $(DIR)main.cpp $(MESSAGES)
SRC= $(DIR)AudioInterface.cpp $(DIR)AudioJS.cpp $(DIR)ColorConverter.cpp $(DIR)Constants.cpp $(DIR)Inflater.cpp $(DIR)Player.cpp $(DIR)ProtocolPreferences.cpp $(DIR)SizedArray.cpp $(DIR)Video.cpp $(DIR)main.cpp $(MESSAGES)
EXPORT=-s "EXPORTED_FUNCTIONS=['_main', '_on_play', '_on_pause', '_set_path']"
PRELOAD= --preload-file TTT/Diskrete_Strukturen_2013_11_21_a/Diskrete_Strukturen_2013_11_21.ttt --preload-file TTT/Diskrete_Strukturen_2013_11_21_a/Diskrete_Strukturen_2013_11_21.mp3
PRELOAD= --preload-file TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.ttt
#STATICLIB= libz.bc
CFLAGS=-O
TEST_LDFLAGS=-L. libz.a
fileplayer.html: $(SRC) pre.js
fileplayer.js: $(SRC) Makefile $(DIR)main.h pre.js
$(EM) $(SRC) $(EXPORT) -o $@ $(PRELOAD) libz.bc #--pre-js pre.js
libz.bc: $(ZSRC)
$(CC) $(ZSRC) -s EXPORT_ALL=1 -o $@
#libz.bc: $(ZSRC)
# $(CC) $(ZSRC) -s EXPORT_ALL=1 -o $@
#libz/%.o: libz/%.c
# $(EM) -fPIC -c $< -o $@
......
......@@ -15,7 +15,16 @@
div.emscripten { text-align: center; }
div.emscripten_border { border: 1px solid black; }
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; }
canvas.emscripten {
border: 0px none;
}
#audioplayer {
border:0px none;
margin:0px none;
padding:0px none;
float:bottom;
width: 100%;
}
#emscripten_logo {
display: inline-block;
......@@ -1197,8 +1206,7 @@
<span id='controls'>
<span><input type="checkbox" id="resize">Resize canvas</span>
<span><input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer &nbsp;&nbsp;&nbsp;</span>
<span><input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
<span><input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked, document.getElementById('resize').checked)">
</span>
</span>
......@@ -1209,6 +1217,13 @@
<div class="emscripten_border">
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<audio class="emscripten" id ="audioplayer" onloadeddata="x_audioLoaded()" onseeking="x_seeked=true;" controls>
<source src="TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.ogg" type="audio/ogg">
<source src="TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.mp3" type="audio/mp3">
<source src="TTT/Diskrete_Strukturen_2013_11_26_a/Diskrete_Strukturen_2013_11_26.wav" type="audio/wav">
Your browser does not support the audio element.
</audio>
<script type="text/javascript" src="Audio.js"></script>
</div>
<textarea id="output" rows="8"></t