Форум программистов, компьютерный форум, киберфорум
8Observer8
Войти
Регистрация
Восстановить пароль

SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer

Запись от 8Observer8 размещена 08.02.2026 в 23:05. Обновил(-а) 8Observer8 10.02.2026 в 19:50
Показов 1799 Комментарии 0

Содержание блога

Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по касанию холста на мобильных устройствах. Запустить финальную демку в браузере можно по ссылке. Скачать результат: finish-play-sound-wasm-sdl3-c.zip

Подключение библиотек SDL3 и SDL3_mixer к стартовому примеру



  • Установите Emscripten 4.0.15 и CMake по инструкции: Установка Emscripten SDK (emsdk) и CMake
  • Скачайте стартовый пример: start-play-sound-wasm-sdl3-c.zip
  • Код стартового примера:

    src/main.c

    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    
    #define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
     
    #include <SDL3/SDL.h>
    #include <SDL3/SDL_main.h>
    #include <stdio.h>
     
    static SDL_Window *window = NULL;
    static SDL_Renderer *renderer = NULL;
     
    SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
    {
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        // Отключаем генерацию событий мыши из касаний пальцем
        SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
     
        if (!SDL_CreateWindowAndRenderer("Example", 400, 400, 0, &window, &renderer))
        {
            SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        SDL_SetRenderVSync(renderer, 1);
     
        return SDL_APP_CONTINUE;
    }
     
    SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
    {
        if (event->type == SDL_EVENT_QUIT)
        {
            return SDL_APP_SUCCESS; // End the program, reporting success to the OS
        }
        else if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
        {
            printf("Клик мышью\n");
        }
        else if(event->type == SDL_EVENT_FINGER_DOWN)
        {
            printf("Касание экрана\n");
        }
     
        return SDL_APP_CONTINUE;
    }
     
    SDL_AppResult SDL_AppIterate(void *appstate)
    {
        // Clear the screen
        SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255);
        SDL_RenderClear(renderer);
     
        // Draw here...
     
        // Update the screen
        SDL_RenderPresent(renderer);
        return SDL_APP_CONTINUE;
    }
     
    void SDL_AppQuit(void *appstate, SDL_AppResult result)
    {
        // SDL will clean up the window/renderer for us
    }
  • Откройте папку со стартовым примером в какой-нибудь редакторе кода, например, в Notepad++ или в Sublime Text 4 (ST4): https://www.sublimetext.com/download
  • Скачайте библиотеку SDL3: SDL3-devel-3.4.0-wasm.zip
  • Скачайте библиотеку SDL3_mixer: SDL3_mixer-devel-3.1.2-wasm.zip
  • Извлеките содержимое архивов библиотек в какую-нибудь новую общую папку, например, с именем "libs" на какой-нибудь диск, например, на C. Таким образом, создайте на диске C папку "lib", скопируйте в неё архивы и извлеките их в текущую папку:
  • Примечание. В папках этих библиотек есть конфигурационные файлы для CMake. Мы будем использовать пути следующего вида для подключения этих библиотек в нашем проекте:
  • Скопируйте путь показанный на скриншоте выше, откройте в редакторе кода файл CMakeLists.txt и замените старый путь на новый в строке:
    Bash
    1
    
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
  • Примечание. Важно! После копирования пути замените обратные слеши (косую черту) на прямые
  • То же самое проделайте для подключения библиотеки SDL3_mixer. То есть, зайдите в папку с конфигурационными файлами SDL3_mixer, создайте в CMakeLists.txt переменную SDL3_mixer_DIR и установите ей значение пути. У вас получится две строчки кода в CMakeLists.txt:
    Bash
    1
    2
    3
    4
    
    # Указываем точное местоположение конфигурационных файлов библиотеки SDL3
    # Имя переменной должно строго соответствовать: НазваниеБиблиотеки_DIR
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
    set(SDL3_mixer_DIR "C:/libs/SDL3_mixer-devel-3.1.2-wasm/lib/cmake/SDL3_mixer")
  • Здесь же в файле CMakeLists.txt добавьте команду для проверки наличия библиотеки SDL3_mixer в системе, а если пути к этим библиотекам мы задали неверно, то будет выведена ошибка при конфигурировании проекта:
    Bash
    1
    2
    3
    4
    5
    
    # Проверяем наличие библиотек в системе
    # Если она не будет найдены, CMake прервет настройку с ошибкой
    # REQUIRED - переводится, как «обязательно» или «требуется»
    find_package(SDL3 REQUIRED)
    find_package(SDL3_mixer REQUIRED)
  • Привязываем библиотеку SDL3_mixer к нашему приложению путём добавления SDL3_mixer::SDL3_mixer:

    Было:

    Bash
    1
    
    target_link_libraries(app PRIVATE SDL3::SDL3)
    Стало:

    Bash
    1
    2
    
    # Привязываем библиотеки к нашему приложению (настройка линковки и путей include)
    target_link_libraries(app PRIVATE SDL3_mixer::SDL3_mixer SDL3::SDL3)
  • К этому моменту CMakeLists.txt выглядит так:
    Bash
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    cmake_minimum_required(VERSION 3.21)
    project(start-play-sound-wasm-sdl3-c)
     
    # Задаем название будущего приложения (в Windows это был бы app.exe, а
    # в вебе будет app.js / app.wasm)
    add_executable(app)
     
    # Устанавливаем стандарт C
    set(CMAKE_C_STANDARD 11)
     
    # Указываем точное местоположение конфигурационных файлов библиотеки SDL3
    # Имя переменной должно строго соответствовать: НазваниеБиблиотеки_DIR
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
    set(SDL3_mixer_DIR "C:/libs/SDL3_mixer-devel-3.1.2-wasm/lib/cmake/SDL3_mixer")
     
    # Проверяем наличие библиотек в системе
    # Если она не будет найдены, CMake прервет настройку с ошибкой
    # REQUIRED - переводится, как «обязательно» или «требуется»
    find_package(SDL3 REQUIRED)
    find_package(SDL3_mixer REQUIRED)
     
    # Привязываем библиотеки к нашему приложению (настройка линковки и путей include)
    target_link_libraries(app PRIVATE SDL3_mixer::SDL3_mixer SDL3::SDL3)
     
    # Добавляем исходный код к проекту
    target_sources(app
        PRIVATE
        src/main.c
    )

Тестовая сборка и тестовый запуск стартового примера в браузере на локальном хостинге



  • Откройте консоль (CMD) в корне стартового примера. Для этого можете просто в адресной строке папки (там где путь) написать "cmd" (без кавычек) и нажать Enter
  • В CMD введите команду для конфигурирования:
    Bash
    1
    
    config-web
  • Примечание. "config-web" - это имя bash-файла (батника), который находится в корне папки стартового примера
  • В CMD введите команду сборки проекта:
    Bash
    1
    
    build-web
  • Собранные файлы (app.js и app.wasm) будут скопированы в папку "public/js" (папка "public" лежит в корне проекта)
  • В корне проекта запустите локальный сервер командой:
    Bash
    1
    
    http-server -c-1
  • Примечание 1. Будут выведены адреса:
    Bash
    1
    2
    3
    4
    
    Available on:
      http://192.168.1.65:8080
      http://127.0.0.1:8080
    Hit CTRL-C to stop the server
  • Примечание 2. Адрес 192.168.1.65:8080 можно использовать для запуска приложения на мобильном устройстве, если у вас есть Wi-Fi - просто вводите этот адрес в браузере мобильного устройства и приложение запустится. Если интересен запуск на мобильном устройстве, то пройдите пошаговую инструкцию: Основы отладки веб-приложений на SDL3 по USB и Wi-Fi
  • Откройте новую вкладку в браузере. Если у вас Chrome или Edge, то нажмите Ctrl+Shift+J, чтобы открыть консоль браузера для контроля вывода информации. Если у вас FireFox, то нажмите Ctrl+Shift+K
  • Перейдите по адресу:
    Bash
    1
    
    localhost:8080
  • Примечание. Обновлять страницу после пересборки проекта лучше с очисткой кэша браузера. Для этого (обязательно с открытой консолью браузера) в браузере Chrome нужно найти в левом верхнем углу браузера кнопку обновления страницы (круговая стрелка), нажать по ней правой кнопкой мыши и выбрать "Empty Cache and Hard Reload"
  • Кликайте по серому холсту и наблюдайте вывод текста в консоль. Должно выводиться:
    Code
    1
    
    Клик мышью

Добавление аудио-файла в проект



  • Скачайте аудио-файл: Picked Coin Echo 2.zip
  • Примечание. Это бесплатный файл, который был взят по ссылке
  • Внутри папки стартового примера создайте вложенную папку "assets/audio" и скопируйте в неё скаченный аудио-файл:
    Название: 6fe16441-fcc6-480f-b8fa-f86c60b4a7c2.png
Просмотров: 790

Размер: 3.1 Кб
  • Откройте файл CMakeLists.txt в редакторе кода и скопируйте в него (в конец файла) код для встраивания аудио-файла в файл "app.wasm":
    Bash
    1
    2
    3
    4
    5
    6
    
    # Встраиваем аудио-файл в файл app.wasm
    if (EMSCRIPTEN)
        target_link_options("app" PRIVATE "SHELL:--embed-file \"${CMAKE_CURRENT_SOURCE_DIR}/assets/audio/Picked Coin Echo 2.wav@/assets/audio/Picked Coin Echo 2.wav\"")
     
        set_property(TARGET "app" APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/audio/Picked Coin Echo 2.wav")
    endif()
  • Текущий файл CMakeLists.txt на данный момент:
    Bash
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
    cmake_minimum_required(VERSION 3.21)
    project(start-play-sound-wasm-sdl3-c)
     
    # Задаем название будущего приложения (в Windows это был бы app.exe, а в вебе будет app.js / app.wasm)
    add_executable(app)
     
    # Устанавливаем стандарт C
    set(CMAKE_C_STANDARD 11)
     
    # Указываем точное местоположение конфигурационных файлов библиотеки SDL3
    # Имя переменной должно строго соответствовать: НазваниеБиблиотеки_DIR
    set(SDL3_DIR "C:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
    set(SDL3_mixer_DIR "C:/libs/SDL3_mixer-devel-3.1.2-wasm/lib/cmake/SDL3_mixer")
     
    # Проверяем наличие библиотек в системе
    # Если она не будет найдены, CMake прервет настройку с ошибкой
    # REQUIRED - переводится, как «обязательно» или «требуется»
    find_package(SDL3 REQUIRED)
    find_package(SDL3_mixer REQUIRED)
     
    # Привязываем библиотеки к нашему приложению (настройка линковки и путей include)
    target_link_libraries(app PRIVATE SDL3_mixer::SDL3_mixer SDL3::SDL3)
     
    # Добавляем исходный код к проекту
    target_sources(app
        PRIVATE
        src/main.c
    )
     
    # Встраиваем аудио-файл в файл app.wasm
    if (EMSCRIPTEN)
        target_link_options("app" PRIVATE "SHELL:--embed-file \"${CMAKE_CURRENT_SOURCE_DIR}/assets/audio/Picked Coin Echo 2.wav@/assets/audio/Picked Coin Echo 2.wav\"")
     
        set_property(TARGET "app" APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/audio/Picked Coin Echo 2.wav")
    endif()
  • Аудио-файл добавлен в проект. Таким же образом вы можете добавлять и другие файлы: изображения, шрифты и т.д.

Написание кода для проигрывания звука



Код лучше всего набирать вручную, а не копировать, чтобы быстрее его запоминать. Мы напишем код пошагово - строка за строкой. Эта инструкция базируется на официальном примере hello.c, но мы не будет использовать track. Содержимое файла hello.c:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#define SDL_MAIN_USE_CALLBACKS 1  /* use the callbacks instead of main() */
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3_mixer/SDL_mixer.h>
 
static MIX_Mixer *mixer;
static MIX_Track *track;
static MIX_Audio *audio;
 
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    const char *file;
 
    /* this doesn't have to run very much, so give up tons of CPU time between iterations. */
    SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, "5");
 
    if (argc != 2) {
        SDL_Log("Usage: %s <file_to_play>", argv[0]);
        return SDL_APP_FAILURE;
    }
    file = argv[1];
 
    if (!MIX_Init()) {
        SDL_Log("Couldn't initialize SDL_mixer: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL);
    if (!mixer) {
        SDL_Log("Couldn't create mixer: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    audio = MIX_LoadAudio(mixer, file, true);
    if (!audio) {
        SDL_Log("Couldn't load audio from %s: %s", file, SDL_GetError());
        return SDL_APP_FAILURE;
    }
 
    track = MIX_CreateTrack(mixer);
    if (!track) {
        SDL_Log("Couldn't create track: %s", SDL_GetError());
        return SDL_APP_FAILURE;
    }
    MIX_SetTrackAudio(track, audio);
    MIX_PlayTrack(track, 0);
 
    return SDL_APP_CONTINUE;
}
 
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
{
    if (event->type == SDL_EVENT_QUIT) {
        return SDL_APP_SUCCESS;
    }
    return SDL_APP_CONTINUE;
}
 
SDL_AppResult SDL_AppIterate(void *appstate)
{
    if (MIX_TrackPlaying(track)) {
        return SDL_APP_CONTINUE;
    }
    return SDL_APP_SUCCESS;
}
 
void SDL_AppQuit(void *appstate, SDL_AppResult result)
{
    /* This will close the audio device and free all mixers and audio data */
    MIX_Quit();
}
  • Откройте файл src/main.c в редакторе кода
  • Напишите код включения заголовочного файла SDL_mixer.h в этом месте кода:
    C
    1
    2
    3
    4
    5
    6
    
    #define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
     
    #include <SDL3/SDL.h>
    #include <SDL3/SDL_main.h>
    #include <SDL3_mixer/SDL_mixer.h>
    #include <stdio.h>
  • Напишите код создания двух переменных указателя: mixer и audio после создания окна (window) и рисовальщика (renderer):
    C
    1
    2
    3
    4
    5
    
    static SDL_Window *window = NULL;
    static SDL_Renderer *renderer = NULL;
     
    static MIX_Mixer *mixer = NULL;
    static MIX_Audio *audio = NULL;
  • Примечание 1. Ключевое слово static означает, что имя переменной-указателя будет видимо только в пределах файла.
  • Примечание 2. Для того, чтобы избежать глобальных переменных нужно использовать аргумент appstate (первый аргумент всех 4-x callback-функции SDL3), как в прикреплённом примере этой инструкции по нативной сборки для Android: SDL3 для Android: Работа со звуком через SDL3_mixer
  • В стартовом примере в начале файла main.c есть функция SDL_AppInit(), которая вызывается один раз самой первой:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
    {
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        // Отключаем генерацию событий мыши из касаний пальцем
        SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
     
        if (!SDL_CreateWindowAndRenderer("Example", 400, 400, 0, &window, &renderer))
        {
            SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        SDL_SetRenderVSync(renderer, 1);
     
        return SDL_APP_CONTINUE;
    }
  • На данный момент здесь в начале происходит инициализация библиотеки SDL3 с помощью вызова функции SDL_Init():
    C
    1
    2
    3
    4
    5
    
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
  • Удалите эту строку кода:
    C
    1
    2
    
        // Отключаем генерацию событий мыши из касаний пальцем
        SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
  • Строку выше удалили, чтобы было поведение по умолчанию - пусть клик мыши на Desktop и касание холста на мобильном устройстве приводит к срабатыванию события SDL_EVENT_MOUSE_BUTTON_DOWN в функции SDL_AppEvent():

    Было:

    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
    {
        if (event->type == SDL_EVENT_QUIT)
        {
            return SDL_APP_SUCCESS; // End the program, reporting success to the OS
        }
        else if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
        {
            printf("Клик мышью\n");
        }
        else if(event->type == SDL_EVENT_FINGER_DOWN)
        {
            printf("Касание экрана\n");
        }
     
        return SDL_APP_CONTINUE;
    }
    Стало:

    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
    {
        if (event->type == SDL_EVENT_QUIT)
        {
            return SDL_APP_SUCCESS;
        }
        else if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
        {
            printf("События клика/касания холста\n");
        }
     
        return SDL_APP_CONTINUE;
    }
  • Протестируем изменения. Сейчас у вас должен быть запущен локальный сервер. Откройте ещё одну консоль внутри папки проекта и выполните команду:
    Bash
    1
    
    build-web
  • Примечание. Не нужно выполнять команду "config-web", потому что её требуется вводить только один раз, а далее CMake будет сам проверять перед сборкой были ли изменения в CMakeLists.txt и если изменения были, то CMake сам переконфигурирует проект
  • Если вы закрыли вкладку браузера, то откройте новую, нажмите Ctrl+Shift+J в Chrome/Edge (Ctrl+Shift+K) в FireFox и обновите страницу. Кликайте по серому холсту и вы увидите вывод в консоли при клике.
  • Примечание. Можете подключить смартфон по USB-кабелю и протестировать код: Основы отладки веб-приложений на SDL3 по USB и Wi-Fi Если вы уже пробовали, то перейдите на компьютере по адресу chrome://inspect/#devices Найдите приложение в списке и нажмите "inspect". Вы увидите экран смартфона на компьютере. Касайтесь экрана смартфона и наблюдайте на вывод в консоль браузера Chrome на компьютере
  • Текущий код main.c на данным момент:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    
    #define SDL_MAIN_USE_CALLBACKS 1 // Use the callbacks instead of main()
     
    #include <SDL3/SDL.h>
    #include <SDL3/SDL_main.h>
    #include <SDL3_mixer/SDL_mixer.h>
    #include <stdio.h>
     
    static SDL_Window *window = NULL;
    static SDL_Renderer *renderer = NULL;
     
    static MIX_Mixer *mixer = NULL;
    static MIX_Audio *audio = NULL;
     
    SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
    {
        if (!SDL_Init(SDL_INIT_VIDEO))
        {
            SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        if (!SDL_CreateWindowAndRenderer("Example", 400, 400, 0, &window, &renderer))
        {
            SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
     
        SDL_SetRenderVSync(renderer, 1);
     
        return SDL_APP_CONTINUE;
    }
     
    SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
    {
        if (event->type == SDL_EVENT_QUIT)
        {
            return SDL_APP_SUCCESS;
        }
        else if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
        {
            printf("События клика/касания холста\n");
        }
     
        return SDL_APP_CONTINUE;
    }
     
    SDL_AppResult SDL_AppIterate(void *appstate)
    {
        // Clear the screen
        SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255);
        SDL_RenderClear(renderer);
     
        // Draw here...
     
        // Update the screen
        SDL_RenderPresent(renderer);
        return SDL_APP_CONTINUE;
    }
     
    void SDL_AppQuit(void *appstate, SDL_AppResult result)
    {
        // SDL will clean up the window/renderer for us
    }
  • Текущий код протестирован. Продолжаем добавлять код для воспроизведения звука в браузере
  • Напишите код инициализации SDL3_mixer после вызова функции SDL_Init():
    C
    1
    2
    3
    4
    5
    
        if (!MIX_Init())
        {
            SDL_Log("Couldn't initialize SDL_mixer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
  • После функции SDL_SetRenderVSync() добавьте код создания микшера:
    C
    1
    2
    3
    4
    5
    6
    
        mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL);
        if (!mixer)
        {
            SDL_Log("Couldn't create mixer: %s", SDL_GetError());
            return SDL_APP_FAILURE;
        }
  • После создания микшера добавьте код загрузки аудио файла:
    C
    1
    2
    3
    4
    5
    6
    
        const char *audiofile = "./assets/audio/Picked Coin Echo 2.wav";
        audio = MIX_LoadAudio(mixer, audiofile, false);
        if (!audio)
        {
            SDL_Log("Failed to load '%s': %s", audiofile, SDL_GetError());
        }
  • В функции SDL_AppEvent() добавьте код проигрывания аудио по клику:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
    {
        if (event->type == SDL_EVENT_QUIT)
        {
            return SDL_APP_SUCCESS;
        }
        else if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN)
        {
            // printf("События клика/касания холста\n");
            if (!MIX_PlayAudio(mixer, audio))
            {
                SDL_Log("Failed to play audio: %s", SDL_GetError());
            }
        }
     
        return SDL_APP_CONTINUE;
    }
  • В функции SDL_AppQuit() добавьте функцию освобождения ресурсов:
    C
    1
    2
    3
    4
    5
    6
    7
    8
    
    void SDL_AppQuit(void *appstate, SDL_AppResult result)
    {
        // SDL автоматически закроет окно и очистит рендерер
     
        // Эта функция приведет к закрытию аудиоустройства и
        // освобождению всех микшеров и аудиоданных
        MIX_Quit();
    }
  • Запустите сборку проекта:
    Bash
    1
    
    build-web
  • Обновите страницу на браузере Desktop и на мобильном браузере - и там и там услышите звук при клике мыши по холсту на Desktop и при касании экрана на смартфоне

Сборка в релиз



  • Для сборки в релиз нужно открыть файл "config-web.bat" в редакторе кода и исправить Debug на Release:

    config-web.bat

    Bash
    1
    
    emcmake cmake -S . -B dist -DCMAKE_BUILD_TYPE=Release
  • Выполните команды конфигурирования и сборки:
    Bash
    1
    2
    
    config-web
    build-web
  • Примечание. Вес файлов после сборки в Debug:
    Code
    1
    2
    
    app.js - 377 KB
    app.wasm - 2.16 MB
    Вес файлов после сборки в Release:
    Code
    1
    2
    
    app.js - 184 KB
    app.wasm - 1.53 MB

Развёртывание на бесплатном хостинге Vercel



  • Скачайте установщик Node.js и установите: https://nodejs.org/en/download
  • Установите Vercel следующей командой из консоли глобально:
    Bash
    1
    
    npm i vercel -g
  • Зарегистрируйтесь на Vercel: https://vercel.com/
  • Примечание. В стартовом прмер, который скачали в начале, уже есть файл vercel.json для решения проблемы с загрузкой wasm-файла
  • В консоле в корне проекта выполните команду:
    Bash
    1
    
    vercel login
  • Выполните команду:
    Bash
    1
    
    vercel
  • Примечание. Будут заданы вопросы в консоли. На все вопросы ответьте "y" (yes) (или нажимайте Enter), кроме этих вопросов, на которые нужно ответить "n" (no):
    Code
    1
    2
    3
    
    Link to existing project? no
    Want to modify these settings? no
    Do you want to change additional project settings? no
  • В консоль будет выведен адрес вашего приложения: https://start-play-sound-wasm-sdl3-c.vercel.app
  • Примечание. Когда вы что-то измените в проекте и захотите загрузить изменённое приложение на сервер, то введите команду:
    Bash
    1
    
    vercel --prod

Миниатюры

Нажмите на изображение для увеличения
Название: 69d48c79-af26-4ac3-948b-6cd45d56b939.png
Просмотров: 818
Размер:	4.3 Кб
ID:	11498
Нажмите на изображение для увеличения
Название: 81114b44-2e99-4781-9ca2-aa6eeaf51845.png
Просмотров: 824
Размер:	14.2 Кб
ID:	11501
Вложения
Тип файла: zip start-play-sound-wasm-sdl3-c.zip (4.0 Кб, 37 просмотров)
Тип файла: zip SDL3-devel-3.4.0-wasm.zip (1.22 Мб, 32 просмотров)
Тип файла: zip SDL3_mixer-devel-3.1.2-wasm.zip (165.7 Кб, 37 просмотров)
Тип файла: zip Picked Coin Echo 2.zip (350.1 Кб, 36 просмотров)
Тип файла: zip finish-play-sound-wasm-sdl3-c.zip (355.0 Кб, 74 просмотров)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru