SoundBuffer* SoundEngine::LoadSoundImpl(const string& sound) { SoundBuffer* buffer = 0; // Check if sound is already loaded and cached SoundCache::iterator cachedSound = soundCache.find(sound); if (cachedSound != soundCache.end()) { buffer = cachedSound->second; } else { // Load and cache sound if (soundDecoder.Open(sound)) { buffer = new SoundBuffer(); // length = 0 because we don't know the size if (soundDecoder.Decode(buffer->data, 0) == SOUND_DECODE_COMPLETED) { buffer->chunk = Mix_QuickLoad_RAW(&buffer->data[0], static_cast<Uint32>(buffer->data.size())); soundCache.insert(SoundCache::value_type(sound, buffer)); } else { delete buffer; buffer = 0; } soundDecoder.Close(); } } return buffer; }
/** Start a compressed sound channel */ static glui32 play_compressed(schanid_t chan, char *ext) { SDL_LockAudio(); chan->status = CHANNEL_SOUND; chan->buffered = 1; chan->sdl_channel = Mix_GroupAvailable(FREE); Mix_GroupChannel(chan->sdl_channel, BUSY); SDL_UnlockAudio(); chan->decode = Sound_NewSample(chan->sdl_rwops, ext, output, 65536); Uint32 soundbytes = Sound_Decode(chan->decode); Sound_Sample *sample = chan->decode; chan->sample = Mix_QuickLoad_RAW(sample->buffer, soundbytes); if (chan->sdl_channel < 0) gli_strict_warning("No available sound channels"); if (chan->sdl_channel >= 0 && chan->sample) { SDL_LockAudio(); sound_channels[chan->sdl_channel] = chan; SDL_UnlockAudio(); Mix_Volume(chan->sdl_channel, chan->volume); Mix_ChannelFinished(&sound_completion_callback); if (Mix_PlayChannel(chan->sdl_channel, chan->sample, 0) >= 0) return 1; } gli_strict_warning("play sound failed"); gli_strict_warning(Mix_GetError()); SDL_LockAudio(); cleanup_channel(chan); SDL_UnlockAudio(); return 0; }
int32_t SDLDrv_PCM_Init(int32_t *mixrate, int32_t *numchannels, void * initdata) { int32_t err = 0; int32_t chunksize; uint16_t fmt; UNREFERENCED_PARAMETER(numchannels); UNREFERENCED_PARAMETER(initdata); if (Initialised) { SDLDrv_PCM_Shutdown(); } chunksize = 512; #ifdef __ANDROID__ chunksize = droidinfo.audio_buffer_size; #endif if (*mixrate >= 16000) chunksize *= 2; if (*mixrate >= 32000) chunksize *= 2; err = Mix_OpenAudio(*mixrate, AUDIO_S16SYS, *numchannels, chunksize); if (err < 0) { ErrorCode = SDLErr_OpenAudio; return SDLErr_Error; } if (Mix_QuerySpec(mixrate, &fmt, numchannels)) { if (fmt == AUDIO_U8 || fmt == AUDIO_S8) { ErrorCode = SDLErr_OpenAudio; return SDLErr_Error; } } //Mix_SetPostMix(fillData, NULL); EffectFence = SDL_CreateMutex(); // channel 0 and 1 are actual sounds // dummy channel 2 runs our fillData() callback as an effect Mix_RegisterEffect(2, fillData, NULL, NULL); DummyBuffer = (uint8_t *) calloc(1, chunksize); DummyChunk = Mix_QuickLoad_RAW(DummyBuffer, chunksize); Mix_PlayChannel(2, DummyChunk, -1); Initialised = 1; return SDLErr_Ok; }
/* Notify the sound channel completion */ static void sound_completion_callback(int chan) { channel_t *sound_channel = sound_channels[chan]; if (!sound_channel || Mix_Playing(chan)) { gli_strict_warning("sound callback failed"); return; } if (!sound_channel->buffered || !sound_channel->decode) { if (sound_channel->notify) { gli_event_store(evtype_SoundNotify, 0, sound_channel->resid, sound_channel->notify); } cleanup_channel(sound_channel); sound_channels[chan] = 0; return; } Uint32 soundbytes = Sound_Decode(sound_channel->decode); if (!soundbytes) { sound_channel->loop--; if (!sound_channel->loop) { if (sound_channel->notify) { gli_event_store(evtype_SoundNotify, 0, sound_channel->resid, sound_channel->notify); } cleanup_channel(sound_channel); sound_channels[chan] = 0; return; } else { Sound_Rewind(sound_channel->decode); soundbytes = Sound_Decode(sound_channel->decode); } } Sound_Sample *sample = sound_channel->decode; sound_channel->sample = Mix_QuickLoad_RAW(sample->buffer, soundbytes); Mix_ChannelFinished(&sound_completion_callback); if (Mix_PlayChannel(sound_channel->sdl_channel, sound_channel->sample, FALSE) >= 0) { return; } gli_strict_warning("buffer sound failed"); gli_strict_warning(Mix_GetError()); cleanup_channel(sound_channel); return; }
void I_InitSound() { int i; fprintf( stderr, "I_InitSound: "); SDL_Init(SDL_INIT_AUDIO); I_InitMusic(); Mix_AllocateChannels(NUM_CHANNELS); Mix_ReserveChannels(3); // Initialize external data (all sounds) at start, keep static. for (i=1 ; i<NUMSFX ; i++) { // Alias? Example is the chaingun sound linked to pistol. if (!S_sfx[i].link) { // Load data from WAD file. S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] ); // Samples now 16bit LE stereo, upsampled to double length and padded S_sfx[i].chunk = Mix_QuickLoad_RAW( S_sfx[i].data, lengths[i] ); } else { // Previously loaded already? S_sfx[i].data = S_sfx[i].link->data; lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)]; S_sfx[i].chunk = Mix_QuickLoad_RAW( S_sfx[i].data, lengths[i] ); } } fprintf( stderr, " pre-cached all sound data\n"); // Finished initialization. fprintf(stderr, "I_InitSound: sound module ready\n"); SDL_PauseAudio(0); }
void create_strings_chunks(void) { int i; sample strings_samples[128]; create_strings_base_sample(); for(i=0;i<128;i++) { if(i<0x50)resample_to_instr(&strings,note_freq[i],2,0.2,1.5,3,&strings_samples[i]); else resample_to_instr(&strings,note_freq[i],2,0.001,0.001,0.001,&strings_samples[i]); strings_note_chunk[i]=Mix_QuickLoad_RAW((void *)strings_samples[i].sample_data,strings_samples[i].channels*strings_samples[i].length*2); } }
void create_piano_chunks(void) { int i; sample piano_samples[128]; create_piano_base_sample_low(); create_piano_base_sample_mid(); create_piano_base_sample_high(); for(i=0;i<128;i++) { if(i>0x44) resample_to_instr(&piano_base_high,note_freq[i],2,0.01,0.0064,1.1,&piano_samples[i]); else if((i>0x28)&&(i<0x45))resample_to_instr(&piano_base_mid,note_freq[i],2,0.01,0.0064,1.1,&piano_samples[i]); else if(i<0x29)resample_to_instr(&piano_base_low,note_freq[i],2,0.01,0.4,5,&piano_samples[i]); piano_note_chunk[i]=Mix_QuickLoad_RAW((void *)piano_samples[i].sample_data,piano_samples[i].channels*piano_samples[i].length*2); } }
void AudioMixer::playACMSound(std::string filename) { auto acm = ResourceManager::acmFileType(filename); if (!acm) return; Logger::debug("AudioMixer") << "playing: " << acm->filename() << std::endl; Mix_Chunk *chunk = NULL; auto it = _sfx.find(acm->filename()); if (it != _sfx.end()) { chunk=it->second; } if (!chunk) { acm->init(); auto samples = acm->samples(); uint8_t *memory = new uint8_t [samples * 2]; auto cnt = acm->readSamples((short*)memory, samples)*2; SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, AUDIO_S16LSB, 1, 22050, AUDIO_S16LSB, 2, 22050); //convert from mono to stereo cvt.buf = (Uint8*)malloc(cnt*cvt.len_mult); memcpy(cvt.buf, (uint8_t*)memory, cnt); cvt.len = cnt; SDL_ConvertAudio(&cvt); // free old buffer delete [] memory; // make SDL_mixer chunk chunk = Mix_QuickLoad_RAW(cvt.buf, cvt.len*cvt.len_ratio); if (_sfx.size() > 100) // TODO: make this configurable { Mix_FreeChunk(_sfx.begin()->second); _sfx.erase(_sfx.begin()); } _sfx.insert(std::pair<std::string, Mix_Chunk*>(acm->filename(), chunk)); } Mix_PlayChannel(-1, chunk, 0); }
void create_drum2(void) { int i; double a0,a1,a2,et; drum2_s.frequency=50; drum2_s.length=freq*2; drum2_s.channels=2; drum2_s.sample_data=calloc(drum2_s.length,2); a0=32767; et=10.4/drum2_s.length; for(i=0;i<drum2_s.length;i++) { a1=exp(-et*i); a2=0.5*sin(i*2*M_PI/(double)(freq/drum2_s.frequency))+0.5*(1-(2.0*random()/(double)RAND_MAX)); drum2_s.sample_data[i]=(Sint16)(a0*a1*a2); } drum2=Mix_QuickLoad_RAW((void *)drum2_s.sample_data,drum2_s.length*2); Mix_VolumeChunk(drum2,(int)(MIX_MAX_VOLUME*drum2_volume)); }
void cSound_PC2::Sound_Voc_Load() { for (auto File : gSoundEffects) { auto file = g_Resource->fileGet(File); SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, AUDIO_U8, 1, 8000, AUDIO_U8, 2, 22050); SDL_assert(cvt.needed); cvt.len = (int) file->size(); cvt.buf = (Uint8 *)SDL_malloc(cvt.len * cvt.len_mult); memcpy(cvt.buf, file->data(), file->size()); SDL_ConvertAudio(&cvt); Mix_Chunk* chunk = Mix_QuickLoad_RAW(cvt.buf, cvt.len_cvt); mSoundEffects.push_back(chunk); //SDL_free(cvt.buf); } }
void create_drum1(void) { int i,j; const double a0=32767.0*5; const int h=5; const double a[6]={1.0, 100,50,25,12,6 }; double a1,a2,et,as; drum1_s.frequency=30; drum1_s.length=(0.3)*freq*2; drum1_s.channels=2; drum1_s.sample_data=calloc(drum1_s.length,2); et=10.0/(drum1_s.length); for(i=0;i<drum1_s.length/drum1_s.channels;i++) { a1=exp(-et*i); a2=0;as=0; for(j=1;j<h+1;j++) { a2=a2+a[j]*sin(j*i*2.0*M_PI/(double)(freq/drum1_s.frequency)); as+=a[j]; } //a2=0.8*sin(i*2*M_PI/(double)(freq/drum1_s.frequency))+0.29*sin(i*4*M_PI/(double)(freq/drum1_s.frequency))+0.01*(1-(2.0*random()/(double)RAND_MAX)); a2=a2/as; as=(a0*a1*a2); if(as>32767) as=32767; if(as<(-32767)) as=-32767; drum1_s.sample_data[i*2]=(Sint16)as; drum1_s.sample_data[i*2+1]=(Sint16)-as; } drum1=Mix_QuickLoad_RAW((void *)drum1_s.sample_data,drum1_s.length*2); Mix_VolumeChunk(drum1,(int)(MIX_MAX_VOLUME*drum1_volume)); }
void THMovie::play(const SDL_Rect &destination_rect, int iChannel) { m_destination_rect = SDL_Rect{ destination_rect.x, destination_rect.y, destination_rect.w, destination_rect.h }; if(!m_pRenderer) { m_sLastError = std::string("Cannot play before setting the renderer"); return; } m_pVideoQueue = new THAVPacketQueue(); m_pMoviePictureBuffer->reset(); m_pMoviePictureBuffer->allocate(m_pRenderer, m_pVideoCodecContext->width, m_pVideoCodecContext->height); m_pAudioPacket = nullptr; m_iAudioPacketSize = 0; m_pbAudioPacketData = nullptr; m_iAudioBufferSize = 0; m_iAudioBufferIndex = 0; m_iAudioBufferMaxSize = 0; m_pAudioQueue = new THAVPacketQueue(); m_iCurSyncPts = 0; m_iCurSyncPtsSystemTime = SDL_GetTicks(); if(m_iAudioStream >= 0) { Mix_QuerySpec(&m_iMixerFrequency, nullptr, &m_iMixerChannels); #ifdef CORSIX_TH_USE_FFMPEG m_pAudioResampleContext = swr_alloc_set_opts( m_pAudioResampleContext, m_iMixerChannels==1?AV_CH_LAYOUT_MONO:AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, m_iMixerFrequency, m_pAudioCodecContext->channel_layout, m_pAudioCodecContext->sample_fmt, m_pAudioCodecContext->sample_rate, 0, nullptr); swr_init(m_pAudioResampleContext); #elif defined(CORSIX_TH_USE_LIBAV) m_pAudioResampleContext = avresample_alloc_context(); av_opt_set_int(m_pAudioResampleContext, "in_channel_layout", m_pAudioCodecContext->channel_layout, 0); av_opt_set_int(m_pAudioResampleContext, "out_channel_layout", m_iMixerChannels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(m_pAudioResampleContext, "in_sample_rate", m_pAudioCodecContext->sample_rate, 0); av_opt_set_int(m_pAudioResampleContext, "out_sample_rate", m_iMixerFrequency, 0); av_opt_set_int(m_pAudioResampleContext, "in_sample_fmt", m_pAudioCodecContext->sample_fmt, 0); av_opt_set_int(m_pAudioResampleContext, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); avresample_open(m_pAudioResampleContext); #endif m_pChunk = Mix_QuickLoad_RAW(m_pbChunkBuffer, ms_audioBufferSize); m_iChannel = Mix_PlayChannel(iChannel, m_pChunk, -1); if(m_iChannel < 0) { m_iChannel = -1; m_sLastError = std::string(Mix_GetError()); } else { Mix_RegisterEffect(m_iChannel, th_movie_audio_callback, nullptr, this); } } m_pStreamThread = SDL_CreateThread(th_movie_stream_reader_thread, "Stream", this); m_pVideoThread = SDL_CreateThread(th_movie_video_thread, "Video", this); }
// Volume 0-I2X (1) int CAudioChannel::Start (short nSound, int nSoundClass, fix nVolume, int nPan, int bLooping, int nLoopStart, int nLoopEnd, int nSoundObj, int nSpeed, const char *pszWAV, CFixVector* vPos) { CSoundSample* soundP = NULL; int bPersistent = (nSoundObj > -1) || bLooping || (nVolume > I2X (1)); if (!(pszWAV && *pszWAV && gameOpts->sound.bUseSDLMixer)) { if (nSound < 0) return -1; if (!gameData.pig.sound.nSoundFiles [gameStates.sound.bD1Sound]) return -1; soundP = gameData.pig.sound.sounds [gameStates.sound.bD1Sound] + nSound % gameData.pig.sound.nSoundFiles [gameStates.sound.bD1Sound]; if (!(soundP->data [soundP->bCustom].Buffer () && soundP->nLength [soundP->bCustom])) return -1; } if (m_info.bPlaying) { m_info.bPlaying = 0; if (m_info.nSoundObj > -1) audio.EndSoundObject (m_info.nSoundObj); if (soundQueue.Channel () == audio.FreeChannel ()) soundQueue.End (); } #if USE_OPENAL if (m_info.source == 0xFFFFFFFF) { CFloatVector fPos; DigiALError (); alGenSources (1, &m_info.source); if (DigiALError ()) return -1; alSourcei (m_info.source, AL_BUFFER, soundP->buffer); if (DigiALError ()) return -1; alSourcef (m_info.source, AL_GAIN, ((nVolume < I2X (1)) ? X2F (nVolume) : 1) * 2 * X2F (m_info.nVolume)); alSourcei (m_info.source, AL_LOOPING, (ALuint) ((nSoundObj > -1) || bLooping || (nVolume > I2X (1)))); fPos.Assign (vPos ? *vPos : OBJECTS [LOCALPLAYER.nObject].nPosition.vPos); alSourcefv (m_info.source, AL_POSITION, reinterpret_cast<ALfloat*> (fPos)); alSource3f (m_info.source, AL_VELOCITY, 0, 0, 0); alSource3f (m_info.source, AL_DIRECTION, 0, 0, 0); if (DigiALError ()) return -1; alSourcePlay (m_info.source); if (DigiALError ()) return -1; } #endif #if USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer) { if (m_info.mixChunkP) { Mix_HaltChannel (m_info.nChannel); if (m_info.bBuiltIn) m_info.bBuiltIn = 0; else Mix_FreeChunk (m_info.mixChunkP); m_info.mixChunkP = NULL; } } #endif if (m_info.bResampled) { m_info.sample.Destroy (); m_info.bResampled = 0; } #if USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer) { //resample to two channels m_info.nChannel = audio.FreeChannel (); if (pszWAV && *pszWAV) { if (!(m_info.mixChunkP = LoadAddonSound (pszWAV, &m_info.bBuiltIn))) return -1; } else { int l; if (soundP->bHires) { l = soundP->nLength [soundP->bCustom]; m_info.sample.SetBuffer (soundP->data [soundP->bCustom].Buffer (), 1, l); m_info.mixChunkP = Mix_QuickLoad_WAV (reinterpret_cast<Uint8*> (m_info.sample.Buffer ())); } else { if (gameOpts->sound.bHires [0]) return -1; //cannot mix hires and standard sounds l = Resample (soundP, gameStates.sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K), songManager.MP3 ()); if (l <= 0) return -1; if (nSpeed < I2X (1)) l = Speedup (soundP, nSpeed); #if MAKE_WAV m_info.mixChunkP = Mix_QuickLoad_WAV (reinterpret_cast<Uint8*> (m_info.sample.Buffer ())); #else m_info.mixChunkP = Mix_QuickLoad_RAW (reinterpret_cast<Uint8*> (m_info.sample.Buffer ()), l); #endif } } Mix_VolPan (m_info.nChannel, nVolume, nPan); Mix_PlayChannel (m_info.nChannel, m_info.mixChunkP, bLooping ? -1 : nLoopEnd - nLoopStart); } else #else if (pszWAV && *pszWAV) return -1; #endif { if (gameStates.sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K)) { int l = Resample (soundP, 0, 0); if (l <= 0) return -1; m_info.nLength = l; } else { m_info.sample.SetBuffer (soundP->data [soundP->bCustom].Buffer (), 1, m_info.nLength = soundP->nLength [soundP->bCustom]); } if (nSpeed < I2X (1)) Speedup (soundP, nSpeed); } m_info.nVolume = FixMul (audio.Volume (), nVolume); m_info.nPan = nPan; m_info.nPosition = 0; m_info.nSoundObj = nSoundObj; m_info.nSoundClass = nSoundClass; m_info.bLooped = bLooping; #if USE_OPENAL m_info.loops = bLooping ? -1 : nLoopEnd - nLoopStart + 1; #endif m_info.nSound = nSound; m_info.bPersistent = 0; m_info.bPlaying = 1; m_info.bPersistent = bPersistent; return audio.FreeChannel (); }
void movie_player::play(int iChannel) { if(!renderer) { last_error = std::string("Cannot play before setting the renderer"); return; } video_queue = new av_packet_queue(); movie_picture_buffer->reset(); movie_picture_buffer->allocate(renderer, video_codec_context->width, video_codec_context->height); audio_packet = nullptr; audio_packet_size = 0; audio_packet_data = nullptr; audio_buffer_size = 0; audio_buffer_index = 0; audio_buffer_max_size = 0; audio_queue = new av_packet_queue(); current_sync_pts = 0; current_sync_pts_system_time = SDL_GetTicks(); if(audio_stream_index >= 0) { Mix_QuerySpec(&mixer_frequency, nullptr, &mixer_channels); #ifdef CORSIX_TH_USE_FFMPEG audio_resample_context = swr_alloc_set_opts( audio_resample_context, mixer_channels==1?AV_CH_LAYOUT_MONO:AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, mixer_frequency, audio_codec_context->channel_layout, audio_codec_context->sample_fmt, audio_codec_context->sample_rate, 0, nullptr); swr_init(audio_resample_context); #elif defined(CORSIX_TH_USE_LIBAV) audio_resample_context = avresample_alloc_context(); av_opt_set_int(audio_resample_context, "in_channel_layout", audio_codec_context->channel_layout, 0); av_opt_set_int(audio_resample_context, "out_channel_layout", mixer_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO, 0); av_opt_set_int(audio_resample_context, "in_sample_rate", audio_codec_context->sample_rate, 0); av_opt_set_int(audio_resample_context, "out_sample_rate", mixer_frequency, 0); av_opt_set_int(audio_resample_context, "in_sample_fmt", audio_codec_context->sample_fmt, 0); av_opt_set_int(audio_resample_context, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); avresample_open(audio_resample_context); #endif empty_audio_chunk = Mix_QuickLoad_RAW(audio_chunk_buffer, audio_chunk_buffer_capacity); audio_channel = Mix_PlayChannel(iChannel, empty_audio_chunk, -1); if(audio_channel < 0) { audio_channel = -1; last_error = std::string(Mix_GetError()); Mix_FreeChunk(empty_audio_chunk); } else { Mix_RegisterEffect(audio_channel, th_movie_audio_callback, nullptr, this); } } stream_thread = std::thread(&movie_player::read_streams, this); video_thread = std::thread(&movie_player::run_video, this); }
int DSL_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) ) { Uint16 format; Uint8 *tmp; int channels; int chunksize; if (mixer_initialized) { DSL_SetErrorCode(DSL_MixerActive); return DSL_Error; } _CallBackFunc = CallBackFunc; _BufferStart = BufferStart; _BufferSize = (BufferSize / NumDivisions); _NumDivisions = NumDivisions; _SampleRate = SampleRate; _remainder = 0; format = (MixMode & SIXTEEN_BIT) ? AUDIO_S16SYS : AUDIO_U8; channels = (MixMode & STEREO) ? 2 : 1; /* 23ms is typically ideal (11025,22050,44100) 46ms isn't bad */ chunksize = 512; if (SampleRate >= 16000) chunksize *= 2; if (SampleRate >= 32000) chunksize *= 2; /* // SDL mixer does this already if (MixMode & SIXTEEN_BIT) chunksize *= 2; if (MixMode & STEREO) chunksize *= 2; */ if (Mix_OpenAudio(SampleRate, format, channels, chunksize) < 0) { DSL_SetErrorCode(DSL_MixerInitFailure); return DSL_Error; } /* Mix_SetPostMix(mixer_callback, NULL); */ /* have to use a channel because postmix will overwrite the music... */ Mix_RegisterEffect(0, mixer_callback, NULL, NULL); /* create a dummy sample just to allocate that channel */ blank_buf = (Uint8 *)malloc(4096); memset(blank_buf, 0, 4096); blank = Mix_QuickLoad_RAW(blank_buf, 4096); Mix_PlayChannel(0, blank, -1); mixer_initialized = 1; return DSL_Ok; }
// Volume 0-F1_0 int DigiStartSound (short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj, int speed, char *pszWAV) { int i, starting_channel; struct sound_slot *ssp; digi_sound *gsp; if (!gameStates.sound.digi.bInitialized) return -1; if (!(pszWAV && gameOpts->sound.bUseSDLMixer)) { if (soundnum < 0) return -1; gsp = gameData.pig.snd.sounds [gameOpts->sound.bD1Sound] + soundnum % gameData.pig.snd.nSoundFiles [gameOpts->sound.bD1Sound]; if (!(gsp->data && gsp->length)) return -1; Assert(gsp->data != (void *) -1); } starting_channel = gameStates.sound.digi.nNextChannel; #if 0 //USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer) { do { if ((SoundSlots [gameStates.sound.digi.nNextChannel].soundno == soundnum) && SoundSlots [gameStates.sound.digi.nNextChannel].persistent) goto foundChannel; gameStates.sound.digi.nNextChannel++; if (gameStates.sound.digi.nNextChannel >= gameStates.sound.digi.nMaxChannels) gameStates.sound.digi.nNextChannel = 0; } while (gameStates.sound.digi.nNextChannel != starting_channel); #endif while (1) { if (!SoundSlots [gameStates.sound.digi.nNextChannel].playing) break; if (!SoundSlots [gameStates.sound.digi.nNextChannel].persistent) break; // use this channel! gameStates.sound.digi.nNextChannel++; if (gameStates.sound.digi.nNextChannel >= gameStates.sound.digi.nMaxChannels) gameStates.sound.digi.nNextChannel = 0; if (gameStates.sound.digi.nNextChannel == starting_channel) { //mprintf((1, "OUT OF SOUND CHANNELS!!!\n")); return -1; } } #if 0 } foundChannel: #endif ssp = SoundSlots + gameStates.sound.digi.nNextChannel; if (ssp->playing) { ssp->playing = 0; if (ssp->soundobj > -1) DigiEndSoundObj (ssp->soundobj); if (SoundQ_channel == gameStates.sound.digi.nNextChannel) SoundQEnd(); } #if USE_SDL_MIXER if (ssp->mixChunk) { Mix_HaltChannel (ssp->channel); Mix_FreeChunk (ssp->mixChunk); ssp->mixChunk = NULL; } #endif #ifndef NDEBUG VerifySoundChannelFree (gameStates.sound.digi.nNextChannel); #endif if (ssp->bResampled) { d_free (ssp->samples); ssp->bResampled = 0; } #if USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer) { //resample to two channels ssp->channel = gameStates.sound.digi.nNextChannel; if (pszWAV) { #if 0 if (!(ssp->samples = CFReadData (pszWAV, gameFolders.szDataDir, 0))) return -1; ssp->mixChunk = Mix_QuickLoad_WAV ((Uint8 *) ssp->samples); #else char szWAV [FILENAME_LEN]; if (!CFExtract (pszWAV, gameFolders.szDataDir, 0, "d2x-temp.wav")) return -1; # ifdef _WIN32 sprintf (szWAV, "%s%sd2x-temp.wav", gameFolders.szDataDir, *gameFolders.szDataDir ? "/" : ""); # else sprintf (szWAV, "%s%sd2x-temp.wav", gameFolders.szHomeDir, *gameFolders.szHomeDir ? "/" : ""); # endif ssp->mixChunk = Mix_LoadWAV (szWAV); #endif } else { int l = DigiResampleSound (gsp, ssp, gameOpts->sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K)); if (l <= 0) return -1; if (speed < F1_0) l = DigiSpeedupSound (gsp, ssp, speed); ssp->mixChunk = Mix_QuickLoad_RAW (ssp->samples, l); } Mix_VolPan (gameStates.sound.digi.nNextChannel, volume, pan); Mix_PlayChannel (gameStates.sound.digi.nNextChannel, ssp->mixChunk, looping ? -1 : loop_end - loop_start); } else #else if (pszWAV) return -1; #endif { if (gameOpts->sound.bD1Sound && (gameOpts->sound.digiSampleRate != SAMPLE_RATE_11K)) { int l = DigiResampleSound (gsp, ssp, 0); if (l <= 0) return -1; ssp->length = l; } else { ssp->samples = gsp->data; ssp->length = gsp->length; } if (speed < F1_0) DigiSpeedupSound (gsp, ssp, speed); } ssp->volume = FixMul (gameStates.sound.digi.nVolume, volume); ssp->pan = pan; ssp->position = 0; ssp->soundobj = soundobj; ssp->looped = looping; ssp->soundno = soundnum; ssp->persistent = 0; ssp->playing = 1; ssp->persistent = (soundobj > -1) || looping || (volume > F1_0); i = gameStates.sound.digi.nNextChannel; if (++gameStates.sound.digi.nNextChannel >= gameStates.sound.digi.nMaxChannels) gameStates.sound.digi.nNextChannel = 0; return i; }
int main(int argc, char* argv[]){ SNDFMT* smpls = gen_sin_buffer(); // smpls = snd_load("/media/c5bcf67f-e9eb-4e12-be75-d8b6e09e27ba/olivier/hti/ginf/cpu-emu/cpu-emu/sin.table"); /* // start SDL with audio support */ if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) exit (-1); atexit (SDL_Quit); screen = SDL_SetVideoMode (640, 480, 16, SDL_HWSURFACE); if (screen == NULL) exit (-1); // open SMPFREQ, signed 8bit, system byte order, // stereo audio, using 1024 byte chunks if(Mix_OpenAudio(SMPFREQ, AUDIO_S8, 1, WAVEFORM_LENGTH)==-1) { printf("Mix_OpenAudio: %s\n", Mix_GetError()); exit(2); } Mix_AllocateChannels(SID_VOICES_NR); Mix_Chunk *sound = NULL; sound = Mix_QuickLoad_RAW(smpls,WAVEFORM_LENGTH); if(sound == NULL) { fprintf(stderr, "Unable to load WAV file: %s\n", Mix_GetError()); } int channel; int channel2; channel = Mix_PlayChannel(-1, sound, -1); // channel2 = Mix_PlayChannel(-1, sound, -1); if(channel == -1) { fprintf(stderr, "Unable to play WAV file: %s\n", Mix_GetError()); } init_SID(&sid); if(!Mix_RegisterEffect(channel, adsrEffect0, NULL, sid.voicea )) { printf("Mix_RegisterEffect: %s\n", Mix_GetError()); } /* if(!Mix_RegisterEffect(channel, adsrEffect0, NULL, sid.voiceb )) { printf("Mix_RegisterEffect: %s\n", Mix_GetError()); } if(!Mix_RegisterEffect(channel, adsrEffect0, NULL, sid.voicec )) { printf("Mix_RegisterEffect: %s\n", Mix_GetError()); } */ /* play time */ struct sid_6581_voice *voicea = sid.voicea; struct sid_6581_voice *voiceb = sid.voiceb; struct sid_6581_voice *voicec = sid.voicec; int i=0,j=0; for(i=0;i<3;i++){ voicea->frequency = 23436; voicea->control = voicea->control | SID_GATE ; SDL_Delay (50); voicea->frequency = 7382; voicea->attack=200; voicea->decay=20; voicea->sustain = 8; voicea->release=20; voicea->attack = 200; voicea->control = voicea->control & ~SID_GATE ; SDL_Delay (500); voicea->frequency = 14764; voicea->attack=200; voicea->decay=20; voicea->sustain = 6; voicea->release=1000; voicea->control = voicea->control | SID_GATE ; for(j=0;j<10;j++){ SDL_Delay (10); voicea->frequency = 14764+14764*j*1/100; } voicea->control = voicea->control & ~SID_GATE ; voicea->control = voicea->control | SID_GATE ; SDL_Delay (50); voicea->control = voicea->control & ~SID_GATE ; SDL_Delay (50); voicea->frequency = 10440; voicea->control = voicea->control | SID_GATE ; SDL_Delay (50); voicea->control = ((((voicea->control & ~SID_GATE) | SID_SAWT ) & ~SID_PULS ) & ~SID_TRIA ) & ~SID_NOIS ; SDL_Delay (50); voicea->frequency = 7382; voicea->control = voicea->control | SID_GATE ; SDL_Delay (50); voicea->control = voicea->control & ~SID_GATE ; SDL_Delay (50); } /* two voices */ voicea->frequency = 7382; voicea->attack=200; voicea->decay=200; voicea->sustain = 6; voicea->release=1000; voiceb->frequency = 9301; voiceb->attack=120; voiceb->decay=20; voiceb->sustain = 6; voiceb->release=1000; voicea->control = voicea->control | SID_GATE | SID_PULS ; voiceb->control = voiceb->control | SID_GATE | SID_SAWT ; SDL_Delay(400); voicea->control = voicea->control & ~SID_GATE ; voiceb->control = voiceb->control & ~SID_GATE ; SDL_Delay(300); sid.voicea->frequency = 7382; sid.voiceb->frequency = 8286; sid.voicea->control = voicea->control | SID_GATE ; sid.voiceb->control = voiceb->control | SID_GATE ; SDL_Delay(400); sid.voicea->control = voicea->control & ~SID_GATE ; sid.voiceb->control = voiceb->control & ~SID_GATE ; SDL_Delay(300); sid.voicea->frequency = 7382; sid.voiceb->frequency = 8779; sid.voicea->control = voicea->control | SID_GATE ; sid.voiceb->control = voiceb->control | SID_GATE ; SDL_Delay(400); sid.voicea->control = voicea->control & ~SID_GATE ; sid.voiceb->control = voiceb->control & ~SID_GATE ; SDL_Delay(300); sid.voicea->frequency = 7382; sid.voiceb->frequency = 9301; sid.voicea->control = voicea->control | SID_GATE ; sid.voiceb->control = voiceb->control | SID_GATE ; SDL_Delay(400); sid.voicea->control = voicea->control & ~SID_GATE ; sid.voiceb->control = voiceb->control & ~SID_GATE ; SDL_Delay(300); SDL_Event event; int done=0; interface_voice = sid.voicea; while(!done) { while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym){ case SDLK_LEFT: (sid.filter->volume - 1) < 0 ? 0 : sid.filter->volume--; volume-=10; Mix_VolumeChunk(sound, volume); // Mix_VolumeChunk(sound, (volume>MIX_MAX_VOLUME-10) ? (volume = MIX_MAX_VOLUME):(volume-=10) ); printf("SDLK_LEFT volume: %i\n",volume); break; case SDLK_RIGHT: (sid.filter->volume + 1) >16 ? 15 : sid.filter->volume++; volume+=10; Mix_VolumeChunk(sound, volume ); // Mix_VolumeChunk(sound, (volume<10) ? (volume = 0): (volume+=10) ); printf("SDLK_RIGHT volume: %i\n",volume); break; case SDLK_UP: printf("up active\n"); break; case SDLK_DOWN: printf("down active\n"); break; default: handleKey(event.key); break; } break; case SDL_KEYUP: switch(event.key.keysym.sym){ case SDLK_LEFT: break; case SDLK_RIGHT: break; case SDLK_UP: interface_voice->frequency = interface_voice->frequency + interface_voice->frequency*1/100; printf("up in-active\n"); break; case SDLK_DOWN: interface_voice->frequency = interface_voice->frequency - interface_voice->frequency*1/100; printf("down in-active\n"); break; default: handleKey(event.key); break; } break; case SDL_QUIT: done = 1; printf("SDL_QUIT\n"); break; case SDL_MOUSEBUTTONUP: switch(event.button.button){ case SDL_BUTTON_WHEELUP: interface_voice->frequency = interface_voice->frequency + interface_voice->frequency*1/100; break; case SDL_BUTTON_WHEELDOWN: interface_voice->frequency = interface_voice->frequency - interface_voice->frequency*1/100; break; } break; default: /* do nothing */ break; } } // SDL_Flip(screen); SDL_Delay (50); } Mix_FreeChunk(sound); Mix_CloseAudio(); SDL_Quit(); return 0; }
Holder<SoundHandle> SDLAudio::Play(const char* ResRef, int XPos, int YPos, unsigned int flags, unsigned int *length) { // TODO: some panning (void)XPos; (void)YPos; // TODO: flags (void)flags; if (!ResRef) { if (flags & GEM_SND_SPEECH) { Mix_HaltChannel(0); } return Holder<SoundHandle>(); } // TODO: move this loading code somewhere central ResourceHolder<SoundMgr> acm(ResRef); if (!acm) { print("failed acm load\n"); return Holder<SoundHandle>(); } int cnt = acm->get_length(); int riff_chans = acm->get_channels(); int samplerate = acm->get_samplerate(); // Use 16-bit word for memory allocation because read_samples takes a 16 bit alignment short * memory = (short *) malloc(cnt*2); //multiply always with 2 because it is in 16 bits int cnt1 = acm->read_samples( memory, cnt ) * 2; //Sound Length in milliseconds unsigned int time_length = ((cnt / riff_chans) * 1000) / samplerate; if (length) { *length = time_length; } // convert our buffer, if necessary SDL_AudioCVT cvt; SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, riff_chans, samplerate, audio_format, audio_channels, audio_rate); cvt.buf = (Uint8*)malloc(cnt1*cvt.len_mult); memcpy(cvt.buf, (char*)memory, cnt1); cvt.len = cnt1; SDL_ConvertAudio(&cvt); // free old buffer free(memory); // make SDL_mixer chunk Mix_Chunk *chunk = Mix_QuickLoad_RAW(cvt.buf, cvt.len*cvt.len_ratio); if (!chunk) { print("error loading chunk\n"); return Holder<SoundHandle>(); } // play int channel = -1; if (flags & GEM_SND_SPEECH) { channel = 0; } SDL_mutexP(OurMutex); channel = Mix_PlayChannel(channel, chunk, 0); if (channel < 0) { SDL_mutexV(OurMutex); print("error playing channel\n"); return Holder<SoundHandle>(); } assert((unsigned int)channel < channel_data.size()); channel_data[channel] = cvt.buf; SDL_mutexV(OurMutex); // TODO return Holder<SoundHandle>(); }
int main(int argc, char* argv[]){ foutp=fopen("data.out", "w"); close(foutp); //smpls = gen_triangle_buffer(); // smpls = gen_sawtooth_buffer(); smpls = snd_load("/media/c5bcf67f-e9eb-4e12-be75-d8b6e09e27ba/olivier/hti/ginf/cpu-emu/cpu-emu/sin.table"); /* //sound_buffer = malloc(sizeof(SNDFMT)*512); */ /* // mem[0] = malloc(sizeof(SNDFMT)*mem0size); */ /* // mem[1] = malloc(sizeof(SNDFMT)*mem1size); */ /* // init without mixer init_sdl (); */ /* // start SDL with audio support */ if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) exit (-1); atexit (SDL_Quit); screen = SDL_SetVideoMode (640, 480, 16, SDL_HWSURFACE); if (screen == NULL) exit (-1); // open SMPFREQ, signed 8bit, system byte order, // stereo audio, using 1024 byte chunks if(Mix_OpenAudio(SMPFREQ, AUDIO_S8, 1, WAVEFORM_LENGTH)==-1) { printf("Mix_OpenAudio: %s\n", Mix_GetError()); exit(2); } Mix_Chunk *sound = NULL; sound = Mix_QuickLoad_RAW(smpls,WAVEFORM_LENGTH); if(sound == NULL) { fprintf(stderr, "Unable to load WAV file: %s\n", Mix_GetError()); } int channel; channel = Mix_PlayChannel(-1, sound, -1); if(channel == -1) { fprintf(stderr, "Unable to play WAV file: %s\n", Mix_GetError()); } //while(Mix_Playing(channel) != 0); int len = WAVEFORM_LENGTH; smpls = gen_sin_buffer(); save("sin.out",smpls,len); smpls = gen_triangle_buffer(); save("triangle.out",smpls,len); smpls = gen_sawtooth_buffer(); save("sawtooth.out",smpls,len); smpls = gen_square_buffer(); save("square.out",smpls,len); smpls = gen_pwm_buffer(0.2); save("pwm.out",smpls,len); // violine int attack = 500; int decay = 300; int sustain = 10; int sustainlength0 = (attack / 1000.0) * SMPFREQ; int sustain_max = 15; // 4 Bit 0-15 float sustain0 = (float) sustain * ((float)1.0)/(float)sustain_max; float sustain_level = sustain0; int release = 750; int release0 = (release / 1000.0) * SMPFREQ; int attack0 = (attack / 1000.0) * SMPFREQ; int decay0 = (decay / 1000.0) * SMPFREQ; int t1 = attack0; int t2 = t1 + decay0; int t3 = t2 + sustainlength0; int t4 = t3 + release0; instrument[0].a_attack = ((float)1.0/(float)attack0); instrument[0].a_decay = ((float) ( 1.0 - sustain0)) / (float) ( t1-t2) ; instrument[0].b_decay = (float)1.0 - ((float)instrument[0].a_decay*(float)attack0); instrument[0].a_release = sustain_level / (float) (t3-t4) ; instrument[0].b_release = sustain_level - (float)instrument[0].a_release * (float)t3; instrument[0].adsr_counter = 0; instrument[0].gate=0; adsr_length = gen_adsr_buffer(&adsr_buffer); saveadsr("data.out",adsr_buffer,adsr_length); savebuffer = malloc(sizeof(float)*adsr_length); // register adsrEffect as a mix processor if(!Mix_RegisterEffect(channel, adsrEffect, NULL, &(instrument[0]) )) { printf("Mix_RegisterEffect: %s\n", Mix_GetError()); } /* Mix_VolumeChunk(sound, volume); */ /* printf("volume: %d\n", volume); */ /* Hz=440; */ /* // main_synthesiser(1, NULL); */ /* printf("start play\n"); */ /* // play (); */ /* // SDL_MixAudio(stream, waveptr, len, SDL_MIX_MAXVOLUME); */ int i=0; SDL_Event event; int done=0; int hzinc=0,amplitudeinc; /* float* adsrptr; int len; saveadsr("data.out",adsrptr,len); if(smp_index < WAVEFORM_LENGTH){ for(i = 0; i < len; i++){ adsrptr[i] = adsrptr[i] * smpls[(int)smp_index]; // smp_index +=freq; smp_index++; if(smp_index >= WAVEFORM_LENGTH) smp_index = 0; } } Mix_CloseAudio(); SDL_Quit(); return 0; */ while(!done) { while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: switch(event.key.keysym.sym){ case SDLK_LEFT: volume-=10; Mix_VolumeChunk(sound, volume); // Mix_VolumeChunk(sound, (volume>MIX_MAX_VOLUME-10) ? (volume = MIX_MAX_VOLUME):(volume-=10) ); printf("SDLK_LEFT volume: %i\n",volume); amplitudeinc = -1; break; case SDLK_RIGHT: volume+=10; Mix_VolumeChunk(sound, volume ); // Mix_VolumeChunk(sound, (volume<10) ? (volume = 0): (volume+=10) ); printf("SDLK_RIGHT volume: %i\n",volume); amplitudeinc = +1;; break; case SDLK_UP: hzinc = 1; printf("up active\n"); break; case SDLK_DOWN: hzinc = -1; printf("down active\n"); break; default: handleKey(event.key); break; } break; case SDL_KEYUP: switch(event.key.keysym.sym){ case SDLK_LEFT: amplitudeinc = 0; break; case SDLK_RIGHT: amplitudeinc = 0; break; case SDLK_UP: tonstufe++; hzinc = 0; printf("up in-active\n"); break; case SDLK_DOWN: tonstufe--; hzinc = 0; printf("down in-active\n"); break; default: handleKey(event.key); break; } break; case SDL_QUIT: done = 1; printf("SDL_QUIT\n"); break; case SDL_MOUSEBUTTONUP: switch(event.button.button){ case SDL_BUTTON_WHEELUP: Hz += 1; break; case SDL_BUTTON_WHEELDOWN: Hz -= 1; break; } break; default: /* do nothing */ break; } } freq += hzinc; //Hz= 2*Hz; Hz = Hz + hzinc; amplitude = amplitude + amplitudeinc; // printf("Hz: %f\n",Hz); //% Hz = frequency(music[i++%10]); int y; // SDL_Flip(screen); SDL_Delay (50); } // save("sndout6.snd"); saveadsr("adsr.out",savebuffer,adsr_length); Mix_FreeChunk(sound); Mix_CloseAudio(); SDL_Quit(); return 0; }