Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editsound.c')
-rw-r--r--source/blender/src/editsound.c1017
1 files changed, 1017 insertions, 0 deletions
diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c
new file mode 100644
index 00000000000..53a3628aa48
--- /dev/null
+++ b/source/blender/src/editsound.c
@@ -0,0 +1,1017 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <fcntl.h>
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_packedFile_types.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_sound.h"
+#include "BKE_library.h"
+#include "BKE_packedFile.h"
+
+#include "BIF_space.h"
+#include "BIF_screen.h"
+#include "BIF_interface.h"
+#include "BIF_editsound.h"
+#include "BIF_mywindow.h"
+
+#include "BSE_drawipo.h"
+#include "BSE_headerbuttons.h"
+
+#include "blendef.h"
+
+#include "interface.h"
+#include "mydevice.h"
+
+#include "SND_C-api.h"
+#include "SND_DependKludge.h"
+
+#include "SYS_System.h"
+
+#include "license_key.h"
+
+extern int LICENSE_KEY_VALID;
+
+/* this might move to the external header */
+void* sound_get_libraryinterface(void);
+
+static SND_SceneHandle ghSoundScene;
+static SND_AudioDeviceInterfaceHandle ghAudioDeviceInterface;
+
+/* que? why only here? because of the type define? */
+bSound *sound_find_sound(char *id_name);
+void sound_read_wav_data(bSound * sound, PackedFile * pf);
+void sound_stop_sound(void *object, bSound *sound);
+void winqreadsoundspace(unsigned short event, short val, char ascii);
+/* void sound_stop_all_sounds(void); already in BIF_editsound.h */
+
+
+
+/* Right. Now for some implementation: */
+void winqreadsoundspace(unsigned short event, short val, char ascii)
+{
+ float dx, dy;
+ int doredraw= 0, cfra, first = 0;
+ short mval[2];
+
+ if(curarea->win==0) return;
+
+ if(val) {
+
+ if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+
+ switch(event)
+ {
+ case LEFTMOUSE:
+ if( view2dmove()==0 )
+ {
+ do
+ {
+ getmouseco_areawin(mval);
+ areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
+
+ cfra = (int)dx;
+ if(cfra< 1) cfra= 1;
+
+ if( cfra!=CFRA || first )
+ {
+ first= 0;
+ CFRA= cfra;
+ update_for_newframe();
+ force_draw_plus(SPACE_VIEW3D);
+ }
+
+ } while(get_mbut()&L_MOUSE);
+
+ }
+ break;
+ case MIDDLEMOUSE:
+ view2dmove(); /* in drawipo.c */
+ break;
+ case RIGHTMOUSE:
+ /* mouse_select_seq(); */
+ break;
+ case PADPLUSKEY:
+ dx= (float)(0.1154*(G.v2d->cur.xmax-G.v2d->cur.xmin));
+ G.v2d->cur.xmin+= dx;
+ G.v2d->cur.xmax-= dx;
+ test_view2d(G.v2d, curarea->winx, curarea->winy);
+
+ doredraw= 1;
+ break;
+ case PADMINUS:
+ dx= (float)(0.15*(G.v2d->cur.xmax-G.v2d->cur.xmin));
+ G.v2d->cur.xmin-= dx;
+ G.v2d->cur.xmax+= dx;
+ test_view2d(G.v2d, curarea->winx, curarea->winy);
+
+ doredraw= 1;
+ break;
+ case HOMEKEY:
+ do_sound_buttons(B_SOUNDHOME);
+ break;
+ }
+ }
+
+ if(doredraw)
+ scrarea_queue_winredraw(curarea);
+}
+
+
+
+void sound_initialize_sounds(void)
+{
+ bSound* sound;
+
+ /* clear the soundscene */
+ SND_RemoveAllSounds(ghSoundScene);
+ SND_RemoveAllSamples(ghSoundScene);
+
+ /* initialize sounds */
+ sound = G.main->sound.first;
+ while (sound)
+ {
+ sound_sample_is_null(sound);
+ sound = (bSound *) sound->id.next;
+ }
+}
+
+
+
+bSound* sound_make_copy(bSound* originalsound)
+{
+ bSound* sound = NULL;
+ char name[160];
+ int len;
+
+ /* only copy sounds that are sounds */
+ if (originalsound)
+ {
+ /* do some name magic */
+ strcpy(name, originalsound->name);
+ len = strlen(name);
+ while ((len > 0) && (name[len - 1] != '/') && (name[len - 1] != '\\'))
+ len--;
+
+ /* allocate the needed memory */
+ sound = alloc_libblock(&G.main->sound, ID_SO, name + len);
+
+ /* create a soundobject */
+ sound->snd_sound = SND_CreateSound();
+
+ /* set the samplename */
+ strcpy(sound->name, name);
+ SND_SetSampleName(sound->snd_sound, sound->name);
+
+ /* add the new object to the soundscene */
+ SND_AddSound(ghSoundScene, sound->snd_sound);
+
+ /* and copy the data from the original */
+ sound->attenuation = originalsound->attenuation;
+ sound->distance = originalsound->distance;
+ sound->max_gain = originalsound->max_gain;
+ sound->min_gain = originalsound->min_gain;
+ sound->newpackedfile = originalsound->newpackedfile;
+ sound->panning = originalsound->panning;
+ sound->pitch = originalsound->pitch;
+ sound->sample = originalsound->sample;
+ sound->volume = originalsound->volume;
+
+ if (originalsound->flags & SOUND_FLAGS_3D)
+ sound->flags |= SOUND_FLAGS_3D;
+ else
+ sound->flags &= ~SOUND_FLAGS_3D;
+ }
+
+ return sound;
+}
+
+
+
+void sound_initialize_sample(bSound* sound)
+{
+ if (sound && sound->sample == NULL)
+ sound_sample_is_null(sound);
+}
+
+
+
+void sound_read_wav_data(bSound* sound, PackedFile* pf)
+{
+ int i, temp;
+ short shortbuf, *temps;
+ int longbuf;
+ char buffer[25];
+ char *data = NULL;
+ char *tempc;
+ bSample *sample = NULL;
+ int channels, rate, bits, len;
+
+ /* prepare for the worst... */
+ sound->sample->type = SAMPLE_INVALID;
+
+ rewindPackedFile(pf);
+
+ /* check to see if it is a file in "RIFF WAVE fmt" format */
+ if (readPackedFile(pf, buffer, 16) != 16)
+ {
+ if (G.f & G_DEBUG) printf("File too short\n");
+ return;
+ }
+
+ if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
+ {
+ readPackedFile(pf, &i, 4);// start of data
+ if(G.order==B_ENDIAN)
+ SWITCH_INT(i);
+
+ /* read the sampleformat */
+ readPackedFile(pf, &shortbuf, 2);
+ if(G.order==B_ENDIAN)
+ {
+ /* was SWITCH_SHORT before */
+ char s_i, *p_i;
+ p_i= (char *)&(shortbuf);
+ s_i= p_i[0];
+ p_i[0]= p_i[1];
+ p_i[1]= s_i;
+ }
+
+ /* read the number of channels */
+ readPackedFile(pf, &shortbuf, 2);
+ if(G.order==B_ENDIAN)
+ {
+ /* was SWITCH_SHORT before */
+ char s_i, *p_i;
+ p_i= (char *)&(shortbuf);
+ s_i= p_i[0];
+ p_i[0]= p_i[1];
+ p_i[1]= s_i;
+ }
+
+ /* check the number of channels */
+ if(shortbuf != 1 && shortbuf != 2)
+ {
+ if (G.f & G_DEBUG) printf("Unsupported number of channels\n");
+ return;
+ }
+ channels = shortbuf;
+
+ /* read the samplerate */
+ readPackedFile(pf, &longbuf, 4);
+ if(G.order==B_ENDIAN)
+ SWITCH_INT(longbuf);
+ rate = longbuf;
+
+ /* read the bitrate */
+ // Ton's way
+ readPackedFile(pf, &temp, 4);
+ if(G.order==B_ENDIAN)
+ SWITCH_INT(temp);
+
+ if(channels && rate)
+ bits= 8*temp/(rate * channels);
+
+ // Frank's way
+ readPackedFile(pf, &shortbuf, 2);
+ readPackedFile(pf, &shortbuf, 2);
+ if(G.order==B_ENDIAN)
+ {
+ /* was SWITCH_SHORT before */
+ char s_i, *p_i;
+ p_i= (char *)&(shortbuf);
+ s_i= p_i[0];
+ p_i[0]= p_i[1];
+ p_i[1]= s_i;
+ }
+ bits = shortbuf;
+
+ seekPackedFile(pf, i-16, SEEK_CUR);
+ readPackedFile(pf, buffer, 4);
+
+ /* check if we have a 'data' chunk */
+ while(memcmp(buffer, "data", 4)!=0)
+ {
+ if (readPackedFile(pf, &i, 4) != 4)
+ break;
+
+ if(G.order==B_ENDIAN)
+ SWITCH_INT(i);
+
+ seekPackedFile(pf, i, SEEK_CUR);
+
+ if (readPackedFile(pf, buffer, 4) != 4)
+ break;
+ }
+
+ /* guess not */
+ if (memcmp(buffer, "data", 4) !=0)
+ {
+ if (G.f & G_DEBUG) printf("No data found\n");
+ }
+ /* or maybe we do! */
+ else
+ {
+ readPackedFile(pf, &longbuf, 4);
+ if(G.order==B_ENDIAN) SWITCH_INT(longbuf);
+
+ /* handle 8 and 16 bit samples differently */
+ if (bits == 8)
+ data = (char *)MEM_mallocN(2 * longbuf, "sample data");
+ else if (bits == 16)
+ data = (char *)MEM_mallocN(longbuf, "sample data");
+
+ len = longbuf;
+
+ if(data)
+ {
+ readPackedFile(pf, data, len);
+
+ /* data is only used to draw! */
+ if (bits == 8)
+ {
+ temps = (short *) data;
+ tempc = (char *) data;
+ for (i = len - 1; i >= 0; i--)
+ temps[i] = tempc[i] << 8;
+ }
+ else
+ {
+ if(G.order==B_ENDIAN)
+ {
+ temps= (short *)data;
+ for(i=0; i< len / 2; i++, temps++)
+ {
+ /* was SWITCH_SHORT before */
+ char s_i, *p_i;
+ p_i= (char *)&(temps);
+ s_i= p_i[0];
+ p_i[0]= p_i[1];
+ p_i[1]= s_i;
+ }
+ }
+ }
+
+ /* fill the sound with the found data */
+ sample = sound->sample;
+ sample->channels = channels;
+ sample->rate = rate;
+ sample->bits = bits;
+ sample->len = len;
+ sample->data = data;
+ sample->type = SAMPLE_WAV;
+ }
+ }
+ }
+ else
+ {
+ sound->sample->type = SAMPLE_INVALID;
+ if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name);
+ }
+}
+
+
+
+/* ugly, but it works (for now) */
+int sound_get_filetype_from_header(bSound* sound, PackedFile* pf)
+{
+ int i, filetype = SAMPLE_INVALID;
+ char buffer[25];
+ short shortbuf;
+
+ rewindPackedFile(pf);
+
+ if (readPackedFile(pf, buffer, 16) != 16)
+ {
+ if (G.f & G_DEBUG) printf("File too short\n");
+ return filetype;
+ }
+
+ if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
+ {
+ readPackedFile(pf, &i, 4);
+ if(G.order==B_ENDIAN)
+ SWITCH_INT(i);
+
+ /* read the sampleformat */
+ readPackedFile(pf, &shortbuf, 2);
+ if(G.order==B_ENDIAN)
+ {
+ char s_i, *p_i;
+ p_i= (char *)&(shortbuf);
+ s_i= p_i[0];
+ p_i[0]= p_i[1];
+ p_i[1]= s_i;
+ }
+
+ if (shortbuf == SND_WAVE_FORMAT_PCM)
+ {
+ filetype = SAMPLE_WAV;
+ }
+ else
+ /* only fmod supports compressed wav */
+#ifdef USE_FMOD
+ {
+ /* and only valid publishers may use compressed wav */
+ if (LICENSE_KEY_VALID)
+ {
+ switch (shortbuf)
+ {
+ case SND_WAVE_FORMAT_ADPCM:
+ case SND_WAVE_FORMAT_ALAW:
+ case SND_WAVE_FORMAT_MULAW:
+ case SND_WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
+ case SND_WAVE_FORMAT_CONTROL_RES_VQLPC:
+ case SND_WAVE_FORMAT_GSM_610:
+ case SND_WAVE_FORMAT_MPEG3:
+ filetype = SAMPLE_WAV;
+ break;
+ default:
+#endif
+ {
+ filetype = SAMPLE_INVALID;
+ if (G.f & G_DEBUG) printf("Unsupported wav compression\n");
+ }
+ }
+#ifdef USE_FMOD
+ }
+ }
+ }
+ /* only valid publishers may use ogg vorbis */
+ else if (!memcmp(buffer, "OggS", 4) && LICENSE_KEY_VALID)
+ {
+ filetype = SAMPLE_OGG_VORBIS;
+ }
+ /* only valid publishers may use mp3 */
+ else if (((!memcmp(buffer, "ID3", 3)) || (!memcmp(buffer, "ÿû", 2))) && LICENSE_KEY_VALID)
+ {
+ filetype = SAMPLE_MP3;
+ }
+#endif
+ else
+ {
+ filetype = SAMPLE_INVALID;
+ if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name);
+ }
+
+ return filetype;
+}
+
+
+
+int check_filetype(bSound* sound, PackedFile* pf)
+{
+// char* pdest;
+ sound->sample->type = SAMPLE_INVALID;
+/*
+ // parse the name for the extension to see what kind of sample it is
+ pdest = strrchr(sound->sample->name, '.');
+
+ // a simple check to see what kind of sample we're dealing with
+ if (stricmp(pdest, ".wav") == 0)
+ sound->sample->type = SAMPLE_WAV;
+
+#ifdef USE_FMOD
+ if (stricmp(pdest, ".mp2") == 0)
+ sound->sample->type = SAMPLE_MP2;
+ if (stricmp(pdest, ".mp3") == 0)
+ sound->sample->type = SAMPLE_MP3;
+ if (stricmp(pdest, ".ogg") == 0)
+ sound->sample->type = SAMPLE_OGG_VORBIS;
+ if (stricmp(pdest, ".raw") == 0)
+ sound->sample->type = SAMPLE_RAW;
+ if (stricmp(pdest, ".wma") == 0)
+ sound->sample->type = SAMPLE_WMA;
+ if (stricmp(pdest, ".asf") == 0)
+ sound->sample->type = SAMPLE_ASF;
+#endif
+*/
+ sound->sample->type = sound_get_filetype_from_header(sound, pf);
+
+ /* get some info from the sample */
+ switch (sound->sample->type)
+ {
+ case SAMPLE_WAV:
+ {
+ sound_read_wav_data(sound, pf);
+ break;
+ }
+ case SAMPLE_OGG_VORBIS:
+ case SAMPLE_MP3:
+ case SAMPLE_MP2:
+ case SAMPLE_RAW:
+ case SAMPLE_WMA:
+ case SAMPLE_ASF:
+ break;
+ default:
+ {
+ if (G.f & G_DEBUG) printf("No valid sample: %s\n", sound->name);
+ break;
+ }
+ }
+
+ return sound->sample->type;
+}
+
+
+
+int sound_load_sample(bSound* sound)
+{
+ int result = FALSE;
+ PackedFile* pf;
+ int freePF = FALSE;
+ int buffer = -1;
+
+ /* check the sample (valid?) */
+ if (sound->sample->type == SAMPLE_UNKNOWN || sound->snd_sound == NULL)
+ {
+ /* find... */
+ pf = sound_find_packedfile(sound);
+
+ /* ...or create a (temp)packedfile */
+ if (pf == NULL)
+ {
+ pf = newPackedFile(sound->name);
+
+ /* if autopack is off, free the pf afterwards */
+ if ((G.fileflags & G_AUTOPACK) == 0)
+ freePF = TRUE;
+ }
+
+ /* if we have a valid pf... */
+ if (pf)
+ {
+ /* check the content of the pf */
+ check_filetype(sound, pf);
+
+ /* check if the sampletype is supported */
+ if (sound->sample->type != SAMPLE_INVALID && sound->sample->type != SAMPLE_UNKNOWN)
+ {
+ /* register the sample at the audiodevice */
+ buffer = SND_AddSample(ghSoundScene, sound->sample->name, pf->data, pf->size);
+
+ /* create a soundobject */
+ sound->snd_sound = SND_CreateSound();
+ SND_SetSampleName(sound->snd_sound, sound->sample->name);
+
+ /* add the soundobject to the soundscene */
+ if (SND_CheckBuffer(ghSoundScene, sound->snd_sound))
+ SND_AddSound(ghSoundScene, sound->snd_sound);
+ else
+ if (G.f & G_DEBUG) printf("error: sample didn't load properly\n");
+
+ /* if it was places in buffer[0] or higher, it succeeded */
+ if (buffer >= 0)
+ result = TRUE;
+ }
+ /* if not, free the pf */
+ else
+ {
+ freePF = TRUE;
+ }
+
+ /* if you want it freed, make it so */
+ if (freePF)
+ {
+ freePackedFile(pf);
+ pf = NULL;
+ }
+ /* or else connect the pf to the sound and sample */
+// else
+// {
+ sound->newpackedfile = pf;
+ sound->sample->packedfile = pf;
+// }
+ }
+ else
+ {
+ if (G.f & G_DEBUG) printf("%s: File not found!\n", sound->name);
+ sound->sample->type = SAMPLE_INVALID;
+ }
+ }
+ /* if the sample ain't invalid, we're ready to go! */
+ else if (sound->sample->type != SAMPLE_INVALID)
+ {
+ result = TRUE;
+ }
+
+ return result;
+}
+
+
+
+bSound* sound_new_sound(char* name)
+{
+ bSound *sound = NULL;
+ int len, file;
+ char str[FILE_MAXDIR+FILE_MAXFILE];
+
+ /* convert the name to absolute path */
+ strcpy(str, name);
+ BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+
+ /* check if the sample on disk can be opened */
+ file = open(str, O_BINARY|O_RDONLY);
+
+ if (file != -1)
+ {
+ close(file);
+
+ /* do some name magic */
+ len = strlen(name);
+ while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
+ len--;
+
+ /* allocate some memory for the sound */
+ sound = alloc_libblock(&G.main->sound, ID_SO, name + len);
+ strcpy(sound->name, name);
+
+ /* intialize and check the sample */
+ sound_initialize_sample(sound);
+
+ /* load the sample & check if this blender supports the sound format */
+// sound_load_sample(sound);
+
+ if (sound->sample->type == SAMPLE_INVALID)
+ {
+ free_libblock(&G.main->sound, sound);
+ sound = NULL;
+ }
+ else
+ {
+ sound->volume = 1.0;
+ sound->attenuation = 1.0;
+ sound->distance = 1.0;
+ sound->min_gain = 0.0;
+ sound->max_gain = 1.0;
+ }
+ }
+
+ return (sound);
+}
+
+
+
+int sound_set_sample(bSound *sound, bSample *sample)
+{
+ int result = TRUE;
+
+ /* decrease the usernumber for this sample */
+ if (sound->sample)
+ sound->sample->id.us--;
+
+ /* delete the soundobject */
+ if (sound->snd_sound)
+ {
+ SND_RemoveSound(ghSoundScene, sound->snd_sound);
+ sound->snd_sound = NULL;
+ }
+
+ /* connect the sample to the sound */
+ sound->sample = sample;
+ sound->newpackedfile = NULL;
+
+ /* increase the usercount */
+ if (sound->sample)
+ {
+ sound->sample->id.us++;
+
+ /* and set the right pf */
+ sound->newpackedfile = sample->packedfile;
+
+ /* if the sampletype is unknown initialize it */
+ if (sound->sample->type == SAMPLE_UNKNOWN)
+ {
+ sound_initialize_sample(sound);
+
+ /* load the sample & check if this blender supports the sound format */
+ if (!sound_load_sample(sound))
+ {
+ result = FALSE;
+ }
+ }
+ }
+ return result;
+}
+
+
+
+bSample *sound_new_sample(bSound * sound)
+{
+ bSample *sample = NULL;
+ int len;
+ char *name;
+
+ if (sound != NULL)
+ {
+ name = sound->name;
+ len = strlen(name);
+ /* do some name magic */
+ while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
+ len--;
+
+ /* allocate the memory for the sample */
+ sample = alloc_libblock(samples, ID_SAMPLE, name + len);
+ sample->data = &sample->fakedata[0];
+ sample->type = SAMPLE_UNKNOWN;
+
+ /* some default settings. We get divide by zero if these values are not set */
+ sample->channels = 1;
+ sample->rate = 44100;
+ sample->bits = 16;
+ sample->alindex = SAMPLE_INVALID;
+
+ /* convert sound->name to abolute filename */
+ strcpy(sample->name, sound->name);
+ BLI_convertstringcode(sample->name, G.sce, G.scene->r.cfra);
+
+ /* connect the pf to the sample */
+ if (sound->newpackedfile)
+ sample->packedfile = sound->newpackedfile;
+ else
+ sample->packedfile = sound_find_packedfile(sound);
+ }
+
+ return(sample);
+}
+
+
+
+/* find a sample that might already be loaded */
+bSample* sound_find_sample(bSound* sound)
+{
+ bSample* sample;
+ char name[FILE_MAXDIR + FILE_MAXFILE];
+ char samplename[FILE_MAXDIR + FILE_MAXFILE];
+
+ // convert sound->name to abolute filename
+ strcpy(name, sound->name);
+ BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+
+ /* search through the list of loaded samples */
+ sample = samples->first;
+
+ while (sample)
+ {
+ strcpy(samplename, sample->name);
+ BLI_convertstringcode(samplename, G.sce, G.scene->r.cfra);
+
+ if (strcmp(name, samplename) == 0)
+ {
+ break;
+ }
+ sample = sample->id.next;
+ }
+
+ return (sample);
+}
+
+
+
+int sound_sample_is_null(bSound* sound)
+{
+ int result = FALSE;
+ bSample* sample;
+
+ /* find the right sample or else create one */
+ if (sound->sample == NULL)
+ {
+ /* find... */
+ sample = sound_find_sample(sound);
+
+ /* or a new one? */
+ if (sample == NULL)
+ sample = sound_new_sample(sound);
+
+ if (sound_set_sample(sound, sample))
+ result = TRUE;
+ }
+
+ return result;
+}
+
+
+
+void sound_stop_all_sounds(void)
+{
+ SND_StopAllSounds(ghSoundScene);
+ SND_Proceed(ghAudioDeviceInterface, ghSoundScene);
+}
+
+
+
+void sound_end_all_sounds(void)
+{
+ sound_stop_all_sounds();
+ SND_RemoveAllSounds(ghSoundScene);
+}
+
+
+
+void sound_play_sound(bSound* sound)
+{
+ /* first check if we want sound or not */
+ SND_IsPlaybackWanted(ghSoundScene);
+
+ /* stop all previous sounds */
+ SND_StopAllSounds(ghSoundScene);
+
+ if (sound != NULL && sound->sample != NULL)
+ {
+ /* load the sample if needed */
+ if (sound_load_sample(sound))
+ {
+ /* set all kinds of parameters */
+ SND_SetListenerGain(ghSoundScene, G.listener->gain);
+ SND_SetDopplerFactor(ghSoundScene, G.listener->dopplerfactor);
+ SND_SetDopplerVelocity(ghSoundScene, G.listener->dopplervelocity);
+
+ SND_SetGain((SND_ObjectHandle)sound->snd_sound, (sound->volume));
+ SND_SetPitch((SND_ObjectHandle)sound->snd_sound, (exp((sound->pitch / 12.0) * log(2.0))));
+
+ if (sound->flags & SOUND_FLAGS_LOOP)
+ {
+ SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_NORMAL);
+#ifdef SOUND_UNDER_DEVELOPMENT
+/* SND_SetLoopPoints((SND_ObjectHandle)sound->snd_sound, sound->loopstart, sound->loopend);
+*/
+#endif
+ if (sound->flags & SOUND_FLAGS_BIDIRECTIONAL_LOOP)
+ SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_BIDIRECTIONAL);
+ else
+ SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_NORMAL);
+
+ }
+ else
+ {
+ SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_OFF);
+ }
+
+ if (sound->flags & SOUND_FLAGS_3D)
+ {
+ SND_SetRollOffFactor((SND_ObjectHandle)sound->snd_sound, sound->attenuation);
+ SND_SetReferenceDistance((SND_ObjectHandle)sound->snd_sound, sound->distance);
+ SND_SetMinimumGain((SND_ObjectHandle)sound->snd_sound, sound->min_gain);
+ SND_SetMaximumGain((SND_ObjectHandle)sound->snd_sound, sound->max_gain);
+ }
+ else
+ {
+ SND_SetRollOffFactor((SND_ObjectHandle)sound->snd_sound, 0);
+ SND_SetReferenceDistance((SND_ObjectHandle)sound->snd_sound, 1);
+ SND_SetMinimumGain((SND_ObjectHandle)sound->snd_sound, 1);
+ SND_SetMaximumGain((SND_ObjectHandle)sound->snd_sound, 1);
+ }
+
+ if (G.f & G_DEBUG) printf("Set pitch to: %f\n", SND_GetPitch((SND_ObjectHandle)sound->snd_sound));
+ if (G.f & G_DEBUG) printf("Set gain to: %f\n", SND_GetGain((SND_ObjectHandle)sound->snd_sound));
+ if (G.f & G_DEBUG) printf("Set looping to: %d\n", SND_GetLoopMode((SND_ObjectHandle)sound->snd_sound));
+
+ /* play the sound */
+ SND_StartSound(ghSoundScene, (SND_ObjectHandle)sound->snd_sound);
+
+ /* update the device */
+ SND_Proceed(ghAudioDeviceInterface, ghSoundScene);
+ }
+ }
+ else
+ {
+ if (G.f & G_DEBUG)
+ {
+ printf("uninitialized sound !\n");
+ if (sound)
+ {
+ printf("sound: %p\n", sound);
+ if (sound->sample)
+ {
+ printf("sample: %p\n", sound->sample);
+ if (sound->snd_sound)
+ printf("hSoundObject: %p\n", sound->snd_sound);
+ }
+ }
+ else
+ {
+ printf("sound == NULL\n");
+ }
+ }
+ }
+}
+
+
+
+bSound *sound_find_sound(char *id_name)
+{
+ bSound *sound;
+
+ // look for sound with same *id* name
+ sound = G.main->sound.first;
+ while (sound)
+ {
+ if (strcmp(sound->id.name + 2, id_name) == 0)
+ break;
+
+ sound = sound->id.next;
+ }
+
+ return sound;
+}
+
+
+
+static void sound_init_listener(void)
+{
+ G.listener = MEM_callocN(sizeof(bSoundListener), "soundlistener");
+ G.listener->gain = 1.0;
+ G.listener->dopplerfactor = 1.0;
+ G.listener->dopplervelocity = 1.0;
+}
+
+
+
+void sound_init_audio(void)
+{
+ int noaudio;
+ SYS_SystemHandle hSystem = NULL;
+ ghAudioDeviceInterface = NULL;
+
+ hSystem = SYS_GetSystem();
+ noaudio = SYS_GetCommandLineInt(hSystem,"noaudio",0);
+
+ if (noaudio)
+ SND_SetDeviceType(snd_e_dummydevice);
+
+ ghAudioDeviceInterface = SND_GetAudioDevice();
+ ghSoundScene = SND_CreateScene(ghAudioDeviceInterface);
+
+ sound_init_listener();
+}
+
+
+
+int sound_get_mixrate(void)
+{
+ return MIXRATE;
+}
+
+
+
+static void sound_exit_listener(void)
+{
+ MEM_freeN(G.listener);
+}
+
+
+
+void sound_exit_audio(void)
+{
+ SND_DeleteScene(ghSoundScene);
+ SND_ReleaseDevice();
+ sound_exit_listener();
+}