예제 #1
0
int32_t S_PlayMusic(const char *fn)
{
    if (!ud.config.MusicToggle || fn == NULL)
        return 0;

    int32_t fp = S_OpenAudio(fn, 0, 1);
    if (EDUKE32_PREDICT_FALSE(fp < 0))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: can't open \"%s\" for playback!\n",fn);
        return 0;
    }

    S_StopMusic();

    int32_t MusicLen = kfilelength(fp);

    if (EDUKE32_PREDICT_FALSE(MusicLen < 4))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: empty music file \"%s\"\n", fn);
        kclose(fp);
        return 0;
    }

    ALIGNED_FREE_AND_NULL(MusicPtr);  // in case the following allocation was never freed
    MusicPtr = (char *)Xaligned_alloc(16, MusicLen);
    g_musicSize = kread(fp, (char *)MusicPtr, MusicLen);

    if (EDUKE32_PREDICT_FALSE(g_musicSize != MusicLen))
    {
        OSD_Printf(OSD_ERROR "S_PlayMusic(): error: read %d bytes from \"%s\", expected %d\n",
                   g_musicSize, fn, MusicLen);
        kclose(fp);
        g_musicSize = 0;
        return 0;
    }

    kclose(fp);

    if (!Bmemcmp(MusicPtr, "MThd", 4))
    {
        MUSIC_PlaySong(MusicPtr, MUSIC_LoopSong);
        MusicIsWaveform = 0;
    }
    else
    {
        int32_t const mvol = MASTER_VOLUME(ud.config.MusicVolume);
        MusicVoice = FX_PlayLoopedAuto(MusicPtr, MusicLen, 0, 0,
                                       0, mvol, mvol, mvol,
                                       FX_MUSIC_PRIORITY, MUSIC_ID);
        if (MusicVoice > FX_Ok)
            MusicIsWaveform = 1;
    }

    return 0;
}
예제 #2
0
void playmusic(char *fn)
{
    int fp;
    char * testfn, * extension;

    if(MusicToggle == 0) return;
    if(MusicDevice < 0) return;

    stopmusic();
    
    testfn = (char *) malloc( strlen(fn) + 5 );
    printf("Playing song: %s\n", fn);
    strcpy(testfn, fn);
    extension = strrchr(testfn, '.');

    do {
       if (extension && !Bstrcasecmp(extension, ".mid")) {
	  // we've been asked to load a .mid file, but first
	  // let's see if there's an ogg with the same base name
	  // lying around
           strcpy(extension, ".ogg");
           fp = kopen4load(testfn, 0);
           if (fp >= 0) {
               printf("OGG found: %s\n", testfn);
               free(testfn);
               break;
           }
       }
       free(testfn);

       // just use what we've been given
       fp = kopen4load(fn, 0);
    } while (0);

    if (fp < 0) return;

    MusicLen = kfilelength( fp );
    MusicPtr = (char *) malloc(MusicLen);
    kread( fp, MusicPtr, MusicLen);
    kclose( fp );
    
    if (!memcmp(MusicPtr, "MThd", 4)) {
       MUSIC_PlaySong( MusicPtr, MusicLen, MUSIC_LoopSong );
       MusicIsWaveform = 0;
    } else {
       MusicVoice = FX_PlayLoopedAuto(MusicPtr, MusicLen, 0, 0, 0,
                                      MusicVolume, MusicVolume, MusicVolume,
				      FX_MUSIC_PRIORITY, MUSIC_ID);
       MusicIsWaveform = 1;
    }

    MusicPaused = 0;
}
예제 #3
0
// NOTE: If v3df_follow == 1, x,y,z are considered literal coordinates
int
PlaySound(int num, int *x, int *y, int *z, Voc3D_Flags flags)
{
    VOC_INFOp vp;
    VOC3D_INFOp v3p;
    int pitch = 0;
    short angle, sound_dist;
    int tx, ty, tz;
    uint8_t priority;
    SPRITEp sp=NULL;

    // DEBUG
    //extern SWBOOL Pachinko_Win_Cheat;


    // Don't play game sounds when in menus
    //if (UsingMenus && (*x!=0 || *y!=0 || *z!=0)) return(-1);

    // Weed out parental lock sounds if PLock is active
    if (gs.ParentalLock || Global_PLock)
    {
        unsigned i;

        for (i=0; i<sizeof(PLocked_Sounds); i++)
        {
            if (num == PLocked_Sounds[i])
                return -1;
        }
    }

    if (Prediction)
        return -1;

    if (!gs.FxOn)
        return -1;

    PRODUCTION_ASSERT(num >= 0 && num < DIGI_MAX);

    // Reset voice
    voice = -1;

    // This is used for updating looping sounds in Update3DSounds
    if (Use_SoundSpriteNum && SoundSpriteNum >= 0)
    {
        ASSERT(SoundSpriteNum >= 0 && SoundSpriteNum < MAXSPRITES);
        sp = &sprite[SoundSpriteNum];
    }

    if (gs.Ambient && TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup))  // Look for invalid ambient numbers
    {
        if (num < 0 || num > MAX_AMBIENT_SOUNDS)
        {
            sprintf(ds,"Invalid or out of range ambient sound number %d\n",num);
            PutStringInfo(Player+screenpeek, ds);
            return -1;
        }
    }


    // Call queue management to add sound to play list.
    // 3D sound manager will update playing sound 10x per second until
    // the sound ends, at which time it is removed from both the 3D
    // sound list as well as the actual cache.
    v3p = Insert3DSound();

    // If the ambient flag is set, do a name conversion to point to actual
    // digital sound entry.
    v3p->num = num;
    v3p->priority = 0;
    v3p->FX_Ok = FALSE; // Hasn't played yet

    if (gs.Ambient && TEST(flags,v3df_ambient) && !TEST(flags,v3df_nolookup))
    {
        v3p->maxtics = STD_RANDOM_RANGE(ambarray[num].maxtics);
        flags |= ambarray[num].ambient_flags;   // Add to flags if any
        num = ambarray[num].diginame;
    }

    PRODUCTION_ASSERT(num >= 0 && num < DIGI_MAX);


    // Assign voc to voc pointer
    vp = &voc[num];
    if (UsingMenus && *x==0 && *y==0 && *z==0)  // Menus sound outdo everything
        priority = 100;
    else
        priority = vp->priority;
    v3p->vp = vp;

    // Assign voc info to 3d struct for future reference
    v3p->x = x;
    v3p->y = y;
    v3p->z = z;
    v3p->fx = *x;
    v3p->fy = *y;
    v3p->fz = *z;
    v3p->flags = flags;

    if (flags & v3df_follow)
    {
        tx = *x;
        ty = *y;
        if (!z)
            tz = 0;                     // Some sound calls don't have a z
        // value
        else
            tz = *z;
    }
    else
    {
        // Don't use pointers to coordinate values.
        tx = v3p->fx;
        ty = v3p->fy;
        tz = v3p->fz;
    }

    // Special case stuff for sounds being played in a level
    if (*x==0 && *y==0 && *z==0)
        tx = ty = tz = 0;

    if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0 && sp)
    {
        tx=sp->x;
        ty=sp->y;
        tz=sp->z;
        //CON_Message("Using sp to set tx=%ld,ty=%ld,tz=%ld",tx,ty,tz);
    }

    // Calculate sound angle
    if (flags & v3df_dontpan)               // If true, don't do panning
        angle = 0;
    else
        angle = SoundAngle(tx, ty);

    // Calculate sound distance
    if (tx == 0 && ty == 0 && tz == 0)
        sound_dist = 255;  // Special case for menus sounds,etc.
    else
        sound_dist = SoundDist(tx, ty, tz, vp->voc_distance);

    v3p->doplr_delta = sound_dist;      // Save of distance for doppler
    // effect

//  //DSPRINTF(ds,"sound dist = %d\n",sound_dist);
//  MONO_PRINT(ds);

    // Can the ambient sound see the player?  If not, tone it down some.
    if ((vp->voc_flags & vf_loop) && Use_SoundSpriteNum && SoundSpriteNum >= 0)
    {
        PLAYERp pp = Player+screenpeek;

        //MONO_PRINT("PlaySound:Checking sound cansee");
        if (!FAFcansee(tx, ty, tz, sp->sectnum,pp->posx, pp->posy, pp->posz, pp->cursectnum))
        {
            //MONO_PRINT("PlaySound:Reducing sound distance");
            sound_dist += ((sound_dist/2)+(sound_dist/4));  // Play more quietly
            if (sound_dist > 255) sound_dist = 255;

            // Special Cases
            if (num == DIGI_WHIPME) sound_dist = 255;
        }
    }

    // Assign ambient priorities based on distance
    if (gs.Ambient && TEST(flags, v3df_ambient))
    {
        v3p->priority = v3p->vp->priority - (sound_dist / 26);
        priority = v3p->priority;
    }

    if (!CacheSound(num, CACHE_SOUND_PLAY))
    {
        v3p->flags = v3df_kill;
        v3p->handle = -1;
        v3p->dist = 0;
        v3p->deleted = TRUE;            // Sound init failed, remove it!
        return -1;
    }

    LockSound(num);

    if (sound_dist < 5)
        angle = 0;

    // Check for pitch bending
    if (vp->pitch_lo > vp->pitch_hi)
        ASSERT(vp->pitch_lo <= vp->pitch_hi);

    if (vp->pitch_hi == vp->pitch_lo)
        pitch = vp->pitch_lo;
    else if (vp->pitch_hi != vp->pitch_lo)
        pitch = vp->pitch_lo + (STD_RANDOM_RANGE(vp->pitch_hi - vp->pitch_lo));

#if 0
    // DEBUG
    if (Pachinko_Win_Cheat)
    {
        CheckSndData(__FILE__, __LINE__);
        Pachinko_Win_Cheat = FALSE;
        CON_Message("S O U N D S   C H E C K E D");
    }
#endif

    // Request playback and play it as a looping sound if flag is set.
    if (vp->voc_flags & vf_loop)
    {
        short loopvol=0;

        if ((loopvol = 255-sound_dist) <= 0)
            loopvol = 0;

        if (sound_dist < 255 || (flags & v3df_init))
        {
            voice = FX_PlayLoopedAuto((char *)vp->data, vp->datalen, 0, 0,
                                      pitch, loopvol, loopvol, loopvol, priority, num);
        }
        else
            voice = -1;

    }
    else
    //if(!flags & v3df_init)  // If not initing sound, play it
    if (tx==0 && ty==0 && tz==0)     // It's a non-inlevel sound
    {
        voice = FX_PlayAuto((char *)vp->data, vp->datalen, pitch, 255, 255, 255, priority, num);
    }
    else     // It's a 3d sound
    {
        if (sound_dist < 255)
        {
            voice = FX_PlayAuto3D((char *)vp->data, vp->datalen, FX_ONESHOT, pitch, angle, sound_dist, priority, num);
        }
        else
            voice = -1;
    }

    // If sound played, update our counter
    if (voice > FX_Ok)
    {
        //vp->playing++;
        v3p->FX_Ok = TRUE;
    }
    else
    {
        vp->lock--;
    }

    // Assign voc info to 3d struct for future reference
    v3p->handle = voice;                // Save the current voc handle in struct
    v3p->dist = sound_dist;
    v3p->tics = 0;                      // Reset tics
    if (flags & v3df_init)
        v3p->flags ^= v3df_init;        // Turn init off now

    return voice;
}
예제 #4
0
SWBOOL
PlaySong(char *song_file_name, int cdaudio_track, SWBOOL loop, SWBOOL restart)
{
    if (!gs.MusicOn)
    {
        return FALSE;
    }

    if (DemoMode)
        return FALSE;

    if (!restart)
    {
        if (SongType == SongTypeWave)
        {
            if (SongTrack > 0 && SongTrack == cdaudio_track)
            {
                // ogg replacement for a CD track
                return TRUE;
            }
            else if (SongName && song_file_name && !strcmp(SongName, song_file_name))
            {
                return TRUE;
            }
        }
        else if (SongType == SongTypeMIDI)
        {
            if (SongName && song_file_name && !strcmp(SongName, song_file_name))
            {
                return TRUE;
            }
        }
    }

    StopSong();

    if (!SW_SHAREWARE)
    {
        if (cdaudio_track >= 0)
        {
            char waveformtrack[MAXWAVEFORMTRACKLENGTH];
            Bstrncpy(waveformtrack, gs.WaveformTrackName, MAXWAVEFORMTRACKLENGTH - 1);

            char *numPos = Bstrstr(waveformtrack, "??");

            if (numPos && (numPos-waveformtrack) < MAXWAVEFORMTRACKLENGTH - 2)
            {
                static const char *tracktypes[] = { ".flac", ".ogg" };
                const size_t tracknamebaselen = Bstrlen(waveformtrack);
                size_t i;

                numPos[0] = '0' + (cdaudio_track / 10) % 10;
                numPos[1] = '0' + cdaudio_track % 10;

                for (i = 0; i < ARRAY_SIZE(tracktypes); ++i)
                {
                    waveformtrack[tracknamebaselen] = '\0';
                    Bstrncat(waveformtrack, tracktypes[i], MAXWAVEFORMTRACKLENGTH);

                    if (LoadSong(waveformtrack))
                    {
                        SongVoice = FX_PlayLoopedAuto(SongPtr, SongLength, 0, 0, 0,
                                                      255, 255, 255, FX_MUSIC_PRIORITY, MUSIC_ID);
                        if (SongVoice > FX_Ok)
                        {
                            SongType = SongTypeWave;
                            SongTrack = cdaudio_track;
                            SongName = Bstrdup(waveformtrack);
                            return TRUE;
                        }
                    }
                }

                buildprintf("Can't find CD track %i!\n", cdaudio_track);
            }
            else
            {
                buildprintf("Make sure to have \"??\" as a placeholder for the track number in your WaveformTrackName!\n");
                buildprintf("  e.g. WaveformTrackName = \"MUSIC/Track??\"\n");
            }
        }
    }

    if (!song_file_name || !LoadSong(song_file_name))
    {
        return FALSE;
    }

    if (!memcmp(SongPtr, "MThd", 4))
    {
        MUSIC_PlaySong(SongPtr, /*SongLength,*/  MUSIC_LoopSong);
        SongType = SongTypeMIDI;
        SongName = strdup(song_file_name);
        return TRUE;
    }
    else
    {
        SongVoice = FX_PlayLoopedAuto(SongPtr, SongLength, 0, 0, 0,
                                      255, 255, 255, FX_MUSIC_PRIORITY, MUSIC_ID);
        if (SongVoice > FX_Ok)
        {
            SongType = SongTypeWave;
            SongName = strdup(song_file_name);
            return TRUE;
        }
    }

    return FALSE;
}