4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License. See http://www.blender.org/BL/ for information
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24 * All rights reserved.
26 * The Original Code is: all of this file.
28 * Contributor(s): none yet.
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
44 #define __USE_XOPEN /* Needed for swab on linux */
51 #include "MEM_guardedalloc.h"
53 #include "BLI_blenlib.h"
54 #include "BLI_arithb.h"
56 #include "DNA_object_types.h"
57 #include "DNA_screen_types.h"
58 #include "DNA_scene_types.h"
59 #include "DNA_sound_types.h"
60 #include "DNA_packedFile_types.h"
61 #include "DNA_userdef_types.h"
63 #include "BKE_utildefines.h"
64 #include "BKE_global.h"
66 #include "BKE_sound.h"
67 #include "BKE_library.h"
68 #include "BKE_packedFile.h"
70 #include "BIF_space.h"
71 #include "BIF_screen.h"
72 #include "BIF_interface.h"
73 #include "BIF_editsound.h"
74 #include "BIF_mywindow.h"
76 #include "BSE_drawipo.h"
77 #include "BSE_headerbuttons.h"
83 #include "SND_C-api.h"
84 #include "SND_DependKludge.h"
86 #include "SYS_System.h"
91 /* this might move to the external header */
92 void* sound_get_libraryinterface(void);
94 static SND_SceneHandle ghSoundScene=NULL;
95 static SND_AudioDeviceInterfaceHandle ghAudioDeviceInterface=NULL;
97 /* que? why only here? because of the type define? */
98 bSound *sound_find_sound(char *id_name);
99 void sound_read_wav_data(bSound * sound, PackedFile * pf);
100 void sound_stop_sound(void *object, bSound *sound);
101 void winqreadsoundspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
102 /* void sound_stop_all_sounds(void); already in BIF_editsound.h */
106 /* Right. Now for some implementation: */
107 void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
109 SpaceSound *ssound= spacedata;
110 unsigned short event= evt->event;
113 int doredraw= 0, cfra, first = 0;
115 short mousebut = L_MOUSE;
117 if(curarea->win==0) return;
121 if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
123 /* swap mouse buttons based on user preference */
124 if (U.flag & USER_LMOUSESELECT) {
125 if (event == LEFTMOUSE) {
128 } else if (event == RIGHTMOUSE) {
136 ssound->flag |= SND_CFRA_NUM;
138 getmouseco_areawin(mval);
139 areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
144 if( cfra!=CFRA || first )
148 update_for_newframe();
149 force_draw_plus(SPACE_VIEW3D, 1);
151 else PIL_sleep_ms(30);
153 } while(get_mbut() & mousebut);
154 ssound->flag &= ~SND_CFRA_NUM;
162 view2dmove(event); /* in drawipo.c */
165 nr= pupmenu("Time value%t|Frames %x1|Seconds%x2");
167 if(nr==1) ssound->flag |= SND_DRAWFRAMES;
168 else ssound->flag &= ~SND_DRAWFRAMES;
174 dx= (float)(0.1154*(G.v2d->cur.xmax-G.v2d->cur.xmin));
175 G.v2d->cur.xmin+= dx;
176 G.v2d->cur.xmax-= dx;
177 test_view2d(G.v2d, curarea->winx, curarea->winy);
182 dx= (float)(0.15*(G.v2d->cur.xmax-G.v2d->cur.xmin));
183 G.v2d->cur.xmin-= dx;
184 G.v2d->cur.xmax+= dx;
185 test_view2d(G.v2d, curarea->winx, curarea->winy);
190 do_sound_buttons(B_SOUNDHOME);
196 scrarea_queue_winredraw(curarea);
201 void sound_initialize_sounds(void)
207 /* clear the soundscene */
208 SND_RemoveAllSounds(ghSoundScene);
209 SND_RemoveAllSamples(ghSoundScene);
212 /* initialize sample blocks (doesnt call audio system, needs to be done once after load */
213 sound = G.main->sound.first;
216 sound_sample_is_null(sound);
217 sound = (bSound *) sound->id.next;
223 bSound* sound_make_copy(bSound* originalsound)
225 bSound* sound = NULL;
229 if(ghSoundScene==NULL) sound_init_audio();
231 /* only copy sounds that are sounds */
234 /* do some name magic */
235 strcpy(name, originalsound->name);
237 while ((len > 0) && (name[len - 1] != '/') && (name[len - 1] != '\\'))
240 /* allocate the needed memory */
241 sound = alloc_libblock(&G.main->sound, ID_SO, name + len);
243 /* create a soundobject */
244 sound->snd_sound = SND_CreateSound();
246 /* set the samplename */
247 strcpy(sound->name, name);
248 SND_SetSampleName(sound->snd_sound, sound->name);
250 /* add the new object to the soundscene */
251 SND_AddSound(ghSoundScene, sound->snd_sound);
253 /* and copy the data from the original */
254 sound->attenuation = originalsound->attenuation;
255 sound->distance = originalsound->distance;
256 sound->max_gain = originalsound->max_gain;
257 sound->min_gain = originalsound->min_gain;
258 sound->newpackedfile = originalsound->newpackedfile;
259 sound->panning = originalsound->panning;
260 sound->pitch = originalsound->pitch;
261 sound->sample = originalsound->sample;
262 sound->volume = originalsound->volume;
264 if (originalsound->flags & SOUND_FLAGS_3D)
265 sound->flags |= SOUND_FLAGS_3D;
267 sound->flags &= ~SOUND_FLAGS_3D;
275 void sound_initialize_sample(bSound* sound)
277 if(ghSoundScene==NULL) sound_init_audio();
279 if (sound && sound->sample == NULL)
280 sound_sample_is_null(sound);
284 void sound_read_wav_data(bSound* sound, PackedFile* pf)
287 short shortbuf, *temps;
292 bSample *sample = NULL;
293 int channels, rate, bits, len;
295 /* prepare for the worst... */
296 sound->sample->type = SAMPLE_INVALID;
298 rewindPackedFile(pf);
300 /* check to see if it is a file in "RIFF WAVE fmt" format */
301 if (readPackedFile(pf, buffer, 16) != 16)
303 if (G.f & G_DEBUG) printf("File too short\n");
307 if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
309 readPackedFile(pf, &i, 4);// start of data
310 if(G.order==B_ENDIAN)
313 /* read the sampleformat */
314 readPackedFile(pf, &shortbuf, 2);
315 if(G.order==B_ENDIAN)
317 /* was SWITCH_SHORT before */
319 p_i= (char *)&(shortbuf);
325 /* read the number of channels */
326 readPackedFile(pf, &shortbuf, 2);
328 if(G.order==B_ENDIAN)
330 /* was SWITCH_SHORT before */
332 p_i= (char *)&(shortbuf);
338 /* check the number of channels */
339 if(shortbuf != 1 && shortbuf != 2)
341 if (G.f & G_DEBUG) printf("Unsupported number of channels\n");
346 /* read the samplerate */
347 readPackedFile(pf, &longbuf, 4);
350 if(G.order==B_ENDIAN)
354 /* read the bitrate */
356 readPackedFile(pf, &temp, 4);
358 if(G.order==B_ENDIAN)
362 bits= 8*temp/(rate * channels);
366 readPackedFile(pf, &shortbuf, 2);
367 readPackedFile(pf, &shortbuf, 2);
368 if(G.order==B_ENDIAN)
370 /* was SWITCH_SHORT before */
372 p_i= (char *)&(shortbuf);
379 seekPackedFile(pf, i-16, SEEK_CUR);
380 readPackedFile(pf, buffer, 4);
381 /* check if we have a 'data' chunk */
382 while(memcmp(buffer, "data", 4)!=0)
384 if (readPackedFile(pf, &i, 4) != 4)
387 if(G.order==B_ENDIAN)
390 seekPackedFile(pf, i, SEEK_CUR);
391 if (readPackedFile(pf, buffer, 4) != 4)
396 if (memcmp(buffer, "data", 4) !=0)
398 if (G.f & G_DEBUG) printf("No data found\n");
400 /* or maybe we do! */
403 readPackedFile(pf, &longbuf, 4);
404 if(G.order==B_ENDIAN) SWITCH_INT(longbuf);
406 /* handle 8 and 16 bit samples differently */
407 /* intrr: removed, longbuf is length in bytes, not samples */
409 data = (char *)MEM_mallocN(longbuf, "sample data");
411 data = (char *)MEM_mallocN(longbuf*2, "sample data");
413 len = longbuf /*/ 4.0*/; /* for some strange reason the sample length is off by a factor of 4... */
414 /* intrr's comment: Funny eh, how one 16-bit stereo sample is 4 bytes? :-) */
418 readPackedFile(pf, data, len);
419 /* data is only used to draw! */
422 temps = (short *) data;
423 tempc = (char *) data;
424 for (i = len - 1; i >= 0; i--)
425 temps[i] = tempc[i] << 8;
429 if(G.order==B_ENDIAN)
431 swab(data, data, len);
434 /* fill the sound with the found data */
435 sample = sound->sample;
436 sample->channels = channels;
441 sample->type = SAMPLE_WAV;
447 sound->sample->type = SAMPLE_INVALID;
448 if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name);
454 /* ugly, but it works (for now) */
455 static int sound_get_filetype_from_header(bSound* sound, PackedFile* pf)
457 int filetype = SAMPLE_INVALID;
462 rewindPackedFile(pf);
464 if (readPackedFile(pf, buffer, 16) != 16)
466 if (G.f & G_DEBUG) printf("File too short\n");
470 if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
472 readPackedFile(pf, &i, 4);
473 if(G.order==B_ENDIAN)
476 /* read the sampleformat */
477 readPackedFile(pf, &shortbuf, 2);
478 if(G.order==B_ENDIAN)
481 p_i= (char *)&(shortbuf);
487 if (shortbuf == SND_WAVE_FORMAT_PCM)
489 filetype = SAMPLE_WAV;
492 /* only fmod supports compressed wav */
495 /* and only valid publishers may use compressed wav */
498 case SND_WAVE_FORMAT_ADPCM:
499 case SND_WAVE_FORMAT_ALAW:
500 case SND_WAVE_FORMAT_MULAW:
501 case SND_WAVE_FORMAT_DIALOGIC_OKI_ADPCM:
502 case SND_WAVE_FORMAT_CONTROL_RES_VQLPC:
503 case SND_WAVE_FORMAT_GSM_610:
504 case SND_WAVE_FORMAT_MPEG3:
505 filetype = SAMPLE_WAV;
510 filetype = SAMPLE_INVALID;
511 if (G.f & G_DEBUG) printf("Unsupported wav compression\n");
517 else if (!memcmp(buffer, "OggS", 4))
519 filetype = SAMPLE_OGG_VORBIS;
521 else if ((!memcmp(buffer, "ID3", 3)) || (!memcmp(buffer, "", 2)))
523 filetype = SAMPLE_MP3;
528 filetype = SAMPLE_INVALID;
529 if (G.f & G_DEBUG) printf("Unsupported sound format: %s\n", sound->name);
537 static int check_filetype(bSound* sound, PackedFile* pf)
540 sound->sample->type = SAMPLE_INVALID;
542 // parse the name for the extension to see what kind of sample it is
543 pdest = strrchr(sound->sample->name, '.');
545 // a simple check to see what kind of sample we're dealing with
546 if (stricmp(pdest, ".wav") == 0)
547 sound->sample->type = SAMPLE_WAV;
550 if (stricmp(pdest, ".mp2") == 0)
551 sound->sample->type = SAMPLE_MP2;
552 if (stricmp(pdest, ".mp3") == 0)
553 sound->sample->type = SAMPLE_MP3;
554 if (stricmp(pdest, ".ogg") == 0)
555 sound->sample->type = SAMPLE_OGG_VORBIS;
556 if (stricmp(pdest, ".raw") == 0)
557 sound->sample->type = SAMPLE_RAW;
558 if (stricmp(pdest, ".wma") == 0)
559 sound->sample->type = SAMPLE_WMA;
560 if (stricmp(pdest, ".asf") == 0)
561 sound->sample->type = SAMPLE_ASF;
564 sound->sample->type = sound_get_filetype_from_header(sound, pf);
566 /* get some info from the sample */
567 switch (sound->sample->type)
571 sound_read_wav_data(sound, pf);
574 case SAMPLE_OGG_VORBIS:
583 if (G.f & G_DEBUG) printf("No valid sample: %s\n", sound->name);
588 return sound->sample->type;
593 int sound_load_sample(bSound* sound)
600 if(ghSoundScene==NULL) sound_init_audio();
602 /* check the sample (valid?) */
603 if (sound->sample->type == SAMPLE_UNKNOWN || sound->snd_sound == NULL)
606 pf = sound_find_packedfile(sound);
608 /* ...or create a (temp)packedfile */
611 pf = newPackedFile(sound->name);
613 /* if autopack is off, free the pf afterwards */
614 if ((G.fileflags & G_AUTOPACK) == 0)
618 /* if we have a valid pf... */
621 /* check the content of the pf */
622 check_filetype(sound, pf);
624 /* check if the sampletype is supported */
625 if (sound->sample->type != SAMPLE_INVALID && sound->sample->type != SAMPLE_UNKNOWN)
627 /* register the sample at the audiodevice */
628 buffer = SND_AddSample(ghSoundScene, sound->sample->name, pf->data, pf->size);
630 /* create a soundobject */
631 sound->snd_sound = SND_CreateSound();
632 SND_SetSampleName(sound->snd_sound, sound->sample->name);
634 /* add the soundobject to the soundscene */
635 if (SND_CheckBuffer(ghSoundScene, sound->snd_sound))
636 SND_AddSound(ghSoundScene, sound->snd_sound);
638 if (G.f & G_DEBUG) printf("error: sample didn't load properly\n");
640 /* if it was places in buffer[0] or higher, it succeeded */
644 /* if not, free the pf */
650 /* if you want it freed, make it so */
656 /* or else connect the pf to the sound and sample */
659 sound->newpackedfile = pf;
660 sound->sample->packedfile = pf;
665 if (G.f & G_DEBUG) printf("%s: File not found!\n", sound->name);
666 sound->sample->type = SAMPLE_INVALID;
669 /* if the sample ain't invalid, we're ready to go! */
670 else if (sound->sample->type != SAMPLE_INVALID)
680 bSound* sound_new_sound(char* name)
682 bSound *sound = NULL;
684 char str[FILE_MAXDIR+FILE_MAXFILE];
686 if(ghSoundScene==NULL) sound_init_audio();
688 if (!G.scene->audio.mixrate) G.scene->audio.mixrate = 44100;
689 /* convert the name to absolute path */
691 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
693 /* check if the sample on disk can be opened */
694 file = open(str, O_BINARY|O_RDONLY);
701 /* do some name magic */
703 while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
706 /* allocate some memory for the sound */
707 sound = alloc_libblock(&G.main->sound, ID_SO, name + len);
708 strcpy(sound->name, name);
710 /* intialize and check the sample */
711 sound_initialize_sample(sound);
713 /* load the sample & check if this blender supports the sound format */
714 // sound_load_sample(sound);
716 if (sound->sample->type == SAMPLE_INVALID)
718 free_libblock(&G.main->sound, sound);
724 sound->attenuation = 1.0;
725 sound->distance = 1.0;
726 sound->min_gain = 0.0;
727 sound->max_gain = 1.0;
736 int sound_set_sample(bSound *sound, bSample *sample)
740 if(ghSoundScene==NULL) sound_init_audio();
742 /* decrease the usernumber for this sample */
744 sound->sample->id.us--;
746 /* delete the soundobject */
747 if (sound->snd_sound)
749 SND_RemoveSound(ghSoundScene, sound->snd_sound);
750 sound->snd_sound = NULL;
753 /* connect the sample to the sound */
754 sound->sample = sample;
755 sound->newpackedfile = NULL;
757 /* increase the usercount */
760 sound->sample->id.us++;
762 /* and set the right pf */
763 sound->newpackedfile = sample->packedfile;
765 /* if the sampletype is unknown initialize it */
766 if (sound->sample->type == SAMPLE_UNKNOWN)
768 sound_initialize_sample(sound);
770 /* load the sample & check if this blender supports the sound format */
771 if (!sound_load_sample(sound))
783 bSample *sound_new_sample(bSound * sound)
785 bSample *sample = NULL;
793 /* do some name magic */
794 while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\')
797 /* allocate the memory for the sample */
798 sample = alloc_libblock(samples, ID_SAMPLE, name + len);
799 sample->data = &sample->fakedata[0];
800 sample->type = SAMPLE_UNKNOWN;
802 /* some default settings. We get divide by zero if these values are not set */
803 sample->channels = 1;
804 sample->rate = 44100;
806 sample->alindex = SAMPLE_INVALID;
808 /* convert sound->name to abolute filename */
809 strcpy(sample->name, sound->name);
810 BLI_convertstringcode(sample->name, G.sce, G.scene->r.cfra);
812 /* connect the pf to the sample */
813 if (sound->newpackedfile)
814 sample->packedfile = sound->newpackedfile;
816 sample->packedfile = sound_find_packedfile(sound);
824 /* find a sample that might already be loaded */
825 bSample* sound_find_sample(bSound* sound)
828 char name[FILE_MAXDIR + FILE_MAXFILE];
829 char samplename[FILE_MAXDIR + FILE_MAXFILE];
831 // convert sound->name to abolute filename
832 strcpy(name, sound->name);
833 BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
835 /* search through the list of loaded samples */
836 sample = samples->first;
840 strcpy(samplename, sample->name);
841 BLI_convertstringcode(samplename, G.sce, G.scene->r.cfra);
843 if (strcmp(name, samplename) == 0)
847 sample = sample->id.next;
855 int sound_sample_is_null(bSound* sound)
860 if(ghSoundScene==NULL) sound_init_audio();
862 /* find the right sample or else create one */
863 if (sound->sample == NULL)
866 sample = sound_find_sample(sound);
870 sample = sound_new_sample(sound);
872 if (sound_set_sample(sound, sample))
881 void sound_stop_all_sounds(void)
885 SND_StopAllSounds(ghSoundScene);
886 SND_Proceed(ghAudioDeviceInterface, ghSoundScene);
893 void sound_end_all_sounds(void)
897 sound_stop_all_sounds();
898 SND_RemoveAllSounds(ghSoundScene);
905 void sound_play_sound(bSound* sound)
908 if(ghSoundScene==NULL) sound_init_audio();
910 /* first check if we want sound or not */
911 SND_IsPlaybackWanted(ghSoundScene);
913 /* stop all previous sounds */
914 SND_StopAllSounds(ghSoundScene);
916 if (sound != NULL && sound->sample != NULL)
918 /* load the sample if needed */
919 if (sound_load_sample(sound))
921 /* set all kinds of parameters */
922 SND_SetListenerGain(ghSoundScene, G.listener->gain);
923 SND_SetDopplerFactor(ghSoundScene, G.listener->dopplerfactor);
924 SND_SetDopplerVelocity(ghSoundScene, G.listener->dopplervelocity);
926 SND_SetGain((SND_ObjectHandle)sound->snd_sound, (sound->volume));
927 SND_SetPitch((SND_ObjectHandle)sound->snd_sound, (exp((sound->pitch / 12.0) * log(2.0))));
929 if (sound->flags & SOUND_FLAGS_LOOP)
931 SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_NORMAL);
932 #ifdef SOUND_UNDER_DEVELOPMENT
933 /* SND_SetLoopPoints((SND_ObjectHandle)sound->snd_sound, sound->loopstart, sound->loopend);
936 if (sound->flags & SOUND_FLAGS_BIDIRECTIONAL_LOOP)
937 SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_BIDIRECTIONAL);
939 SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_NORMAL);
944 SND_SetLoopMode((SND_ObjectHandle)sound->snd_sound, SND_LOOP_OFF);
947 if (sound->flags & SOUND_FLAGS_3D)
949 SND_SetRollOffFactor((SND_ObjectHandle)sound->snd_sound, sound->attenuation);
950 SND_SetReferenceDistance((SND_ObjectHandle)sound->snd_sound, sound->distance);
951 SND_SetMinimumGain((SND_ObjectHandle)sound->snd_sound, sound->min_gain);
952 SND_SetMaximumGain((SND_ObjectHandle)sound->snd_sound, sound->max_gain);
956 SND_SetRollOffFactor((SND_ObjectHandle)sound->snd_sound, 0);
957 SND_SetReferenceDistance((SND_ObjectHandle)sound->snd_sound, 1);
958 SND_SetMinimumGain((SND_ObjectHandle)sound->snd_sound, 1);
959 SND_SetMaximumGain((SND_ObjectHandle)sound->snd_sound, 1);
962 if (G.f & G_DEBUG) printf("Set pitch to: %f\n", SND_GetPitch((SND_ObjectHandle)sound->snd_sound));
963 if (G.f & G_DEBUG) printf("Set gain to: %f\n", SND_GetGain((SND_ObjectHandle)sound->snd_sound));
964 if (G.f & G_DEBUG) printf("Set looping to: %d\n", SND_GetLoopMode((SND_ObjectHandle)sound->snd_sound));
967 SND_StartSound(ghSoundScene, (SND_ObjectHandle)sound->snd_sound);
969 /* update the device */
970 SND_Proceed(ghAudioDeviceInterface, ghSoundScene);
977 printf("uninitialized sound !\n");
980 printf("sound: %p\n", sound);
983 printf("sample: %p\n", sound->sample);
984 if (sound->snd_sound)
985 printf("hSoundObject: %p\n", sound->snd_sound);
990 printf("sound == NULL\n");
999 bSound *sound_find_sound(char *id_name)
1003 // look for sound with same *id* name
1004 sound = G.main->sound.first;
1007 if (strcmp(sound->id.name + 2, id_name) == 0)
1010 sound = sound->id.next;
1016 void sound_init_audio(void)
1019 SYS_SystemHandle hSystem = NULL;
1021 if(ghSoundScene==NULL) {
1022 hSystem = SYS_GetSystem();
1023 noaudio = SYS_GetCommandLineInt(hSystem,"noaudio",0);
1025 if (noaudio)/*(noaudio) intrr: disable game engine audio (openal) */
1026 SND_SetDeviceType(snd_e_dummydevice);
1028 ghAudioDeviceInterface = SND_GetAudioDevice();
1029 ghSoundScene = SND_CreateScene(ghAudioDeviceInterface);
1030 // also called after read new file, but doesnt work when no audio initialized
1031 sound_initialize_sounds();
1036 int sound_get_mixrate(void)
1042 void sound_exit_audio(void)
1045 SND_DeleteScene(ghSoundScene);
1046 SND_ReleaseDevice();
1047 ghSoundScene = NULL;