Mercurial > sdl-ios-xcode
comparison src/audio/SDL_audio.c @ 2866:e532417a6977
Fixed SDL 1.2 compatibility problem.
The API specifies that SDL_OpenAudio() will fill out the 'desired' audio spec
with the correct samples and size set by the driver. This value is important
since it may be used by applications that size audio buffers, etc.
However, we want to allow advanced applications to call SDL_OpenAudioDevice()
which gets passed a const 'desired' parameter, and have the correct data filled
into the 'obtained' parameter, possibly allowing or not allowing format changes.
So... 'obtained' becomes the audio format the user callback is expected to use,
and we add flags to allow the application to specify which format changes are
allowed.
Note: We really need to add a way to query the 'obtained' audio spec.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 13 Dec 2008 06:36:47 +0000 |
parents | 99210400e8b9 |
children | 2929ed239d2a |
comparison
equal
deleted
inserted
replaced
2865:09adf4854163 | 2866:e532417a6977 |
---|---|
790 } | 790 } |
791 | 791 |
792 | 792 |
793 static SDL_AudioDeviceID | 793 static SDL_AudioDeviceID |
794 open_audio_device(const char *devname, int iscapture, | 794 open_audio_device(const char *devname, int iscapture, |
795 const SDL_AudioSpec * _desired, SDL_AudioSpec * obtained, | 795 const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, |
796 int min_id) | 796 int allowed_changes, int min_id) |
797 { | 797 { |
798 SDL_AudioDeviceID id = 0; | 798 SDL_AudioDeviceID id = 0; |
799 SDL_AudioSpec desired; | 799 SDL_AudioSpec _obtained; |
800 SDL_AudioDevice *device; | 800 SDL_AudioDevice *device; |
801 SDL_bool build_cvt; | |
801 int i = 0; | 802 int i = 0; |
802 | 803 |
803 if (!SDL_WasInit(SDL_INIT_AUDIO)) { | 804 if (!SDL_WasInit(SDL_INIT_AUDIO)) { |
804 SDL_SetError("Audio subsystem is not initialized"); | 805 SDL_SetError("Audio subsystem is not initialized"); |
805 return 0; | 806 return 0; |
808 if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { | 809 if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { |
809 SDL_SetError("No capture support"); | 810 SDL_SetError("No capture support"); |
810 return 0; | 811 return 0; |
811 } | 812 } |
812 | 813 |
813 if (!prepare_audiospec(_desired, &desired)) { | 814 if (!obtained) { |
815 obtained = &_obtained; | |
816 } | |
817 if (!prepare_audiospec(desired, obtained)) { | |
814 return 0; | 818 return 0; |
815 } | 819 } |
816 | 820 |
817 /* If app doesn't care about a specific device, let the user override. */ | 821 /* If app doesn't care about a specific device, let the user override. */ |
818 if (devname == NULL) { | 822 if (devname == NULL) { |
863 if (device == NULL) { | 867 if (device == NULL) { |
864 SDL_OutOfMemory(); | 868 SDL_OutOfMemory(); |
865 return 0; | 869 return 0; |
866 } | 870 } |
867 SDL_memset(device, '\0', sizeof(SDL_AudioDevice)); | 871 SDL_memset(device, '\0', sizeof(SDL_AudioDevice)); |
868 SDL_memcpy(&device->spec, &desired, sizeof(SDL_AudioSpec)); | 872 device->spec = *obtained; |
869 device->enabled = 1; | 873 device->enabled = 1; |
870 device->paused = 1; | 874 device->paused = 1; |
871 device->iscapture = iscapture; | 875 device->iscapture = iscapture; |
872 | 876 |
873 /* Create a semaphore for locking the sound buffers */ | 877 /* Create a semaphore for locking the sound buffers */ |
884 close_audio_device(device); | 888 close_audio_device(device); |
885 return 0; | 889 return 0; |
886 } | 890 } |
887 device->opened = 1; | 891 device->opened = 1; |
888 | 892 |
889 /* If the audio driver changes the buffer size, accept it */ | |
890 if (device->spec.samples != desired.samples) { | |
891 desired.samples = device->spec.samples; | |
892 SDL_CalculateAudioSpec(&device->spec); | |
893 } | |
894 | |
895 /* Allocate a fake audio memory buffer */ | 893 /* Allocate a fake audio memory buffer */ |
896 device->fake_stream = SDL_AllocAudioMem(device->spec.size); | 894 device->fake_stream = SDL_AllocAudioMem(device->spec.size); |
897 if (device->fake_stream == NULL) { | 895 if (device->fake_stream == NULL) { |
898 close_audio_device(device); | 896 close_audio_device(device); |
899 SDL_OutOfMemory(); | 897 SDL_OutOfMemory(); |
900 return 0; | 898 return 0; |
901 } | 899 } |
902 | 900 |
901 /* If the audio driver changes the buffer size, accept it */ | |
902 if (device->spec.samples != obtained->samples) { | |
903 obtained->samples = device->spec.samples; | |
904 SDL_CalculateAudioSpec(obtained); | |
905 } | |
906 | |
903 /* See if we need to do any conversion */ | 907 /* See if we need to do any conversion */ |
904 if (obtained != NULL) { | 908 build_cvt = SDL_FALSE; |
905 SDL_memcpy(obtained, &device->spec, sizeof(SDL_AudioSpec)); | 909 if (obtained->freq != device->spec.freq) { |
906 } else if (desired.freq != device->spec.freq || | 910 if (allowed_changes & SDL_AUDIO_ALLOW_FREQUENCY_CHANGE) { |
907 desired.format != device->spec.format || | 911 obtained->freq = device->spec.freq; |
908 desired.channels != device->spec.channels) { | 912 } else { |
913 build_cvt = SDL_TRUE; | |
914 } | |
915 } | |
916 if (obtained->format != device->spec.format) { | |
917 if (allowed_changes & SDL_AUDIO_ALLOW_FORMAT_CHANGE) { | |
918 obtained->format = device->spec.format; | |
919 } else { | |
920 build_cvt = SDL_TRUE; | |
921 } | |
922 } | |
923 if (obtained->channels != device->spec.channels) { | |
924 if (allowed_changes & SDL_AUDIO_ALLOW_CHANNELS_CHANGE) { | |
925 obtained->channels = device->spec.channels; | |
926 } else { | |
927 build_cvt = SDL_TRUE; | |
928 } | |
929 } | |
930 if (build_cvt) { | |
909 /* Build an audio conversion block */ | 931 /* Build an audio conversion block */ |
910 if (SDL_BuildAudioCVT(&device->convert, | 932 if (SDL_BuildAudioCVT(&device->convert, |
911 desired.format, desired.channels, | 933 obtained->format, obtained->channels, |
912 desired.freq, | 934 obtained->freq, |
913 device->spec.format, device->spec.channels, | 935 device->spec.format, device->spec.channels, |
914 device->spec.freq) < 0) { | 936 device->spec.freq) < 0) { |
915 close_audio_device(device); | 937 close_audio_device(device); |
916 return 0; | 938 return 0; |
917 } | 939 } |
918 if (device->convert.needed) { | 940 if (device->convert.needed) { |
919 device->convert.len = (int) (((double) desired.size) / | 941 device->convert.len = (int) (((double) obtained->size) / |
920 device->convert.len_ratio); | 942 device->convert.len_ratio); |
921 | 943 |
922 device->convert.buf = | 944 device->convert.buf = |
923 (Uint8 *) SDL_AllocAudioMem(device->convert.len * | 945 (Uint8 *) SDL_AllocAudioMem(device->convert.len * |
924 device->convert.len_mult); | 946 device->convert.len_mult); |
964 return id + 1; | 986 return id + 1; |
965 } | 987 } |
966 | 988 |
967 | 989 |
968 int | 990 int |
969 SDL_OpenAudio(const SDL_AudioSpec * desired, SDL_AudioSpec * obtained) | 991 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) |
970 { | 992 { |
971 SDL_AudioDeviceID id = 0; | 993 SDL_AudioDeviceID id = 0; |
972 | 994 |
973 /* Start up the audio driver, if necessary. This is legacy behaviour! */ | 995 /* Start up the audio driver, if necessary. This is legacy behaviour! */ |
974 if (!SDL_WasInit(SDL_INIT_AUDIO)) { | 996 if (!SDL_WasInit(SDL_INIT_AUDIO)) { |
981 if (open_devices[0] != NULL) { | 1003 if (open_devices[0] != NULL) { |
982 SDL_SetError("Audio device is already opened"); | 1004 SDL_SetError("Audio device is already opened"); |
983 return (-1); | 1005 return (-1); |
984 } | 1006 } |
985 | 1007 |
986 id = open_audio_device(NULL, 0, desired, obtained, 1); | 1008 if (obtained) { |
1009 id = open_audio_device(NULL, 0, desired, obtained, | |
1010 SDL_AUDIO_ALLOW_ANY_CHANGE, 1); | |
1011 } else { | |
1012 id = open_audio_device(NULL, 0, desired, desired, 0, 1); | |
1013 } | |
987 if (id > 1) { /* this should never happen in theory... */ | 1014 if (id > 1) { /* this should never happen in theory... */ |
988 SDL_CloseAudioDevice(id); | 1015 SDL_CloseAudioDevice(id); |
989 SDL_SetError("Internal error"); /* MUST be Device ID #1! */ | 1016 SDL_SetError("Internal error"); /* MUST be Device ID #1! */ |
990 return (-1); | 1017 return (-1); |
991 } | 1018 } |
993 return ((id == 0) ? -1 : 0); | 1020 return ((id == 0) ? -1 : 0); |
994 } | 1021 } |
995 | 1022 |
996 SDL_AudioDeviceID | 1023 SDL_AudioDeviceID |
997 SDL_OpenAudioDevice(const char *device, int iscapture, | 1024 SDL_OpenAudioDevice(const char *device, int iscapture, |
998 const SDL_AudioSpec * desired, SDL_AudioSpec * obtained) | 1025 const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, |
999 { | 1026 int allowed_changes) |
1000 return open_audio_device(device, iscapture, desired, obtained, 2); | 1027 { |
1028 return open_audio_device(device, iscapture, desired, obtained, | |
1029 allowed_changes, 2); | |
1001 } | 1030 } |
1002 | 1031 |
1003 SDL_audiostatus | 1032 SDL_audiostatus |
1004 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) | 1033 SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) |
1005 { | 1034 { |