From 966fe28c59f59fc8be795c8215b9352435982445 Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 30 Sep 2021 16:46:36 +0200 Subject: Merged nGenEx and Parser into Stars45 --- Stars45/Sound.cpp | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 Stars45/Sound.cpp (limited to 'Stars45/Sound.cpp') diff --git a/Stars45/Sound.cpp b/Stars45/Sound.cpp new file mode 100644 index 0000000..d8a634f --- /dev/null +++ b/Stars45/Sound.cpp @@ -0,0 +1,310 @@ +/* Starshatter OpenSource Distribution + Copyright (c) 1997-2004, Destroyer Studios LLC. + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name "Destroyer Studios" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + SUBSYSTEM: nGenEx.lib + FILE: Sound.cpp + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Abstract sound class +*/ + +#include "MemDebug.h" +#include "Sound.h" +#include "SoundCard.h" +#include "Wave.h" + +#include "vorbis/codec.h" +#include "vorbis/vorbisfile.h" + +// +--------------------------------------------------------------------+ + +SoundCard* Sound::creator = 0; + +Sound* +Sound::CreateStream(const char* filename) +{ + Sound* sound = 0; + + if (!filename || !filename[0] || !creator) + return sound; + + int namelen = strlen(filename); + + if (namelen < 5) + return sound; + + if ((filename[namelen-3] == 'o' || filename[namelen-3] == 'O') && + (filename[namelen-2] == 'g' || filename[namelen-2] == 'G') && + (filename[namelen-1] == 'g' || filename[namelen-1] == 'G')) { + + return CreateOggStream(filename); + } + + WAVE_HEADER head; + WAVE_FMT fmt; + WAVE_FACT fact; + WAVE_DATA data; + WAVEFORMATEX wfex; + + ZeroMemory(&head, sizeof(head)); + ZeroMemory(&fmt, sizeof(fmt)); + ZeroMemory(&fact, sizeof(fact)); + ZeroMemory(&data, sizeof(data)); + + LPBYTE buf = 0; + LPBYTE p = 0; + int len = 0; + + FILE* f; + ::fopen_s(&f, filename, "rb"); + + if (f) { + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + + if (len > 4096) { + len = 4096; + } + + buf = new(__FILE__,__LINE__) BYTE[len]; + + if (buf && len) + fread(buf, len, 1, f); + + fclose(f); + } + + + if (len > sizeof(head)) { + CopyMemory(&head, buf, sizeof(head)); + + if (head.RIFF == MAKEFOURCC('R', 'I', 'F', 'F') && + head.WAVE == MAKEFOURCC('W', 'A', 'V', 'E')) { + + p = buf + sizeof(WAVE_HEADER); + + do { + DWORD chunk_id = *((LPDWORD) p); + + switch (chunk_id) { + case MAKEFOURCC('f', 'm', 't', ' '): + CopyMemory(&fmt, p, sizeof(fmt)); + p += fmt.chunk_size + 8; + break; + + case MAKEFOURCC('f', 'a', 'c', 't'): + CopyMemory(&fact, p, sizeof(fact)); + p += fact.chunk_size + 8; + break; + + case MAKEFOURCC('s', 'm', 'p', 'l'): + CopyMemory(&fact, p, sizeof(fact)); + p += fact.chunk_size + 8; + break; + + case MAKEFOURCC('d', 'a', 't', 'a'): + CopyMemory(&data, p, sizeof(data)); + p += 8; + break; + + default: + delete[] buf; + return sound; + } + } + while (data.chunk_size == 0); + + wfex.wFormatTag = fmt.wFormatTag; + wfex.nChannels = fmt.nChannels; + wfex.nSamplesPerSec = fmt.nSamplesPerSec; + wfex.nAvgBytesPerSec = fmt.nAvgBytesPerSec; + wfex.nBlockAlign = fmt.nBlockAlign; + wfex.wBitsPerSample = fmt.wBitsPerSample; + wfex.cbSize = 0; + + sound = Create(Sound::STREAMED, &wfex); + + if (sound) { + sound->SetFilename(filename); + sound->StreamFile(filename, p - buf); + } + } + } + + delete[] buf; + return sound; +} + +// +--------------------------------------------------------------------+ + +Sound* +Sound::CreateOggStream(const char* filename) +{ + Sound* sound = 0; + + if (!filename || !filename[0] || !creator) + return sound; + + int namelen = strlen(filename); + + if (namelen < 5) + return sound; + + WAVEFORMATEX wfex; + ZeroMemory(&wfex, sizeof(wfex)); + + FILE* f; + ::fopen_s(&f, filename, "rb"); + + if (f) { + OggVorbis_File* povf = new(__FILE__,__LINE__) OggVorbis_File; + + if (!povf) { + Print("Sound::CreateOggStream(%s) - out of memory!\n", filename); + return sound; + } + + ZeroMemory(povf, sizeof(OggVorbis_File)); + + if (ov_open(f, povf, NULL, 0) < 0) { + Print("Sound::CreateOggStream(%s) - not an Ogg bitstream\n", filename); + delete povf; + return sound; + } + + Print("\nOpened Ogg Bitstream '%s'\n", filename); + char **ptr=ov_comment(povf,-1)->user_comments; + vorbis_info *vi=ov_info(povf,-1); + while(*ptr){ + Print("%s\n", *ptr); + ++ptr; + } + + Print("Bitstream is %d channel, %ldHz\n", vi->channels, vi->rate); + Print("Decoded length: %ld samples\n", + (long)ov_pcm_total(povf,-1)); + Print("Encoded by: %s\n\n", ov_comment(povf,-1)->vendor); + + wfex.wFormatTag = WAVE_FORMAT_PCM; + wfex.nChannels = vi->channels; + wfex.nSamplesPerSec = vi->rate; + wfex.nAvgBytesPerSec = vi->channels * vi->rate * 2; + wfex.nBlockAlign = vi->channels * 2; + wfex.wBitsPerSample = 16; + wfex.cbSize = 0; + + sound = Create(Sound::STREAMED | Sound::OGGVORBIS, + &wfex, + sizeof(OggVorbis_File), + (LPBYTE) povf); + + sound->SetFilename(filename); + } + + return sound; +} + +// +--------------------------------------------------------------------+ + +Sound* +Sound::Create(DWORD flags, LPWAVEFORMATEX format) +{ + if (creator) return creator->CreateSound(flags, format); + else return 0; +} + +Sound* +Sound::Create(DWORD flags, LPWAVEFORMATEX format, DWORD len, LPBYTE data) +{ + if (creator) return creator->CreateSound(flags, format, len, data); + else return 0; +} + +void +Sound::SetListener(const Camera& cam, const Vec3& vel) +{ + if (creator) + creator->SetListener(cam, vel); +} + +// +--------------------------------------------------------------------+ + +Sound::Sound() + : status(UNINITIALIZED), volume(0), flags(0), looped(0), + velocity(0,0,0), location(0,0,0), sound_check(0) +{ + strcpy_s(filename, "Sound()"); +} + +// +--------------------------------------------------------------------+ + +Sound::~Sound() +{ } + +// +--------------------------------------------------------------------+ + +void +Sound::Release() +{ + flags &= ~LOCKED; +} + +// +--------------------------------------------------------------------+ + +void +Sound::AddToSoundCard() +{ + if (creator) + creator->AddSound(this); +} + +// +--------------------------------------------------------------------+ + +void +Sound::SetFilename(const char* s) +{ + if (s) { + int n = strlen(s); + + if (n >= 60) { + ZeroMemory(filename, sizeof(filename)); + strcpy_s(filename, "..."); + strcat_s(filename, s + n - 59); + filename[63] = 0; + } + + else { + strcpy_s(filename, s); + } + } +} + -- cgit v1.1