반응형

SDL 기본 라이브러리는 WAV 형식의 오디오만 처리할 수 있다. mp3, ogg 등의 형식을 처리하기 위해서는 SDL_mixer 라이브러리가 필요하다.

 

우선 SDL 기본 라이브러리로 WAV 사운드를 출력해 보자.

 

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
#include <iostream>
#include "SDL.h"
 
#pragma comment(lib, "sdl2.lib")
#pragma comment(lib, "sdl2main.lib")
 
int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_AUDIO);
 
    SDL_AudioSpec wav_spec;
    Uint8* wav_buffer;
    Uint32 wav_length;
 
    if (SDL_LoadWAV("sound.wav"&wav_spec, &wav_buffer, &wav_length) == NULL) {
        // Use this function to load a WAVE from a file.
        printf("SDL_LoadWAV Error: %s\n", SDL_GetError());
        return -1;
    }
 
    int bitDepth = SDL_AUDIO_BITSIZE(wav_spec.format);
    int bytesPerSecond = (bitDepth * wav_spec.channels * wav_spec.freq) / 8;
    float durationSec = (float)wav_length / bytesPerSecond;
    printf("Duration: %f\n", durationSec);
    // wav 파일 재생 시간 구하기.
 
    SDL_AudioDeviceID dev = SDL_OpenAudioDevice(NULL0&wav_spec, NULL0);
    // Open a specific audio device.
    if (dev == NULL) {
        printf("SDL_AudioDeviceID Error: %s\n", SDL_GetError());
        return -1;
    }
 
    if (SDL_QueueAudio(dev, wav_buffer, wav_length) != 0) {
        // Queue more audio on non-callback devices.
        printf("SDL_QueueAudio Error: %s\n", SDL_GetError());
        return -1;
    }
 
    SDL_PauseAudioDevice(dev, 0);
    // Use this function to pause and unpause audio playback on a specified device.
    // dev: a device opened by SDL_OpenAudioDevice()
    // pause_on: non-zero to pause, 0 to unpause
    SDL_Delay(durationSec * 1000);
    // Wait a specified number of milliseconds before returning.
 
    SDL_FreeWAV(wav_buffer);
    // Free data previously allocated with SDL_LoadWAV() or SDL_LoadWAV_RW().
    SDL_CloseAudioDevice(dev);
    //Use this function to shut down audio processing and close the audio device.
    SDL_Quit();
 
    return 0;
}
 

 

코드를 작성하고 빌드한다.

 

실행하면 재생 시간이 표시되고 사운드가 출력된다.

 

※ 참고

SDL_AudioFormat

 

이번엔 SDL_mixer를 이용해 mp3, ogg 등의 사운드를 출력해 보자. 아래 링크에서 SDL_mixer를 다운받고 적당히 설치한다.

SDL Libraries

 

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
#include <iostream>
#include "SDL.h"
#include "SDL_mixer.h"
 
#pragma comment(lib, "sdl2.lib")
#pragma comment(lib, "sdl2main.lib")
#pragma comment(lib, "sdl2_mixer.lib")
 
int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_AUDIO);
 
    if (Mix_OpenAudio(48000, MIX_DEFAULT_FORMAT, 22048!= 0) {
        // Open the default audio device for playback.
        printf("Mix_OpenAudio Error: %s\n", Mix_GetError());
        return -1;
    }
 
    Mix_Music* music = Mix_LoadMUS("sound.mp3");
    // Load a supported audio format into a music object.
    if (music == NULL) {
        printf("Mix_LoadMUS Error: %s\n", Mix_GetError());
        return -1;
    }
    printf("Duration: %f\n", Mix_MusicDuration(music));
    // Get a music object's duration, in seconds.
 
    Mix_PlayMusic(music, 0);
    // Play a new music object. (0 means "play once and stop")
    SDL_Delay(int(Mix_MusicDuration(music) * 1000));
 
    Mix_FreeMusic(music);
    // Free a music object. If this music is currently playing,
    // it will be stopped.
    Mix_CloseAudio();
    // Close the mixer, halting all playing audio.
 
    SDL_Quit();
 
    return 0;
}
 

 

코드를 작성하고 빌드한다.

 

실행하면 재생시간이 표시되고 사운드가 출력된다.

 

※ 참고

SDL_mixer API

 

반응형
Posted by J-sean
:
반응형

AudioSwitcher를 이용해 시스템 볼륨을 조정해 보자.

 

AudioSwitcher Nuget Package를 설치한다.

 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
using System.Runtime.InteropServices;
using AudioSwitcher.AudioApi.CoreAudio;
 
namespace ConsoleApp1
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();
 
        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
 
        static void Main(string[] args)
        {
            const int SW_HIDE = 0// 창 숨기기
            const int SW_SHOW = 1// 창 보이기
 
            IntPtr handle = GetConsoleWindow();
            //ShowWindow(handle, SW_HIDE);
 
            CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
            Console.WriteLine("Current Volume: " + defaultPlaybackDevice.Volume);
 
            while (true)
            {
                if (defaultPlaybackDevice.Volume > 20// 볼륨이 20 보다 크다면
                {
                    while (defaultPlaybackDevice.Volume > 20// 볼륨이 20 보다 크지 않을때 까지 무한 루프
                    {
                        defaultPlaybackDevice.Volume--// 볼륨 1 감소
                        Console.WriteLine("Current Volume: " + defaultPlaybackDevice.Volume);
                        System.Threading.Thread.Sleep(1000); // 매 1초 확인
                    }
                }
 
                System.Threading.Thread.Sleep(10000); // 매 10초 확인
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

프로그램을 실행하면 시스템 볼륨이 20 이하일 때까지 1초마다 1씩 감소한다.

 

처음 35였던 볼륨이 20이 되었다.

 

2022.01.07 - [C#] - C# AudioSwitcher System Audio/Sound Volume Control - 시스템 오디오/사운드 볼륨 컨트롤 2

 

반응형
Posted by J-sean
:
반응형

Bartop 게임기 제작에 필요한 부품을 알아 보니 작은 스피커와 앰프도 필요하다는걸 알게 되었다. 가장 비싼 취미 중 하나라는 오디오. 그 취미의 중심에 있는 부품 중 하나인 앰프는 몇 천원부터 수 천만원에 이르기 까지 정말 다양한 가격대가 형성되어 있다. 물론 내가 구입한 제품은 low-end... 그래도 나름배송비 포함 $5.84다. ㅠㅠ


PAM8406 2 Channel Audio Amplifier


PAM8406은 이 제품의 이름이 아니라 사용된 앰프칩의 이름이다.

이 제품은 LQ-AMP10W지만 아무도 그렇게 부르지 않는다.


PAM8406 2 Channel Audio Amplifier

Voltage: 5VDC

Output Power: 5W 2Ω / 3W 4Ω / 1.8W 8Ω

https://www.aliexpress.com/item/32957841305.html?spm=2114.13010708.0.0.3a994c4ddUnkBN



스피커, 전원, 오디오 소스를 연결 한다.


3W 4Ω 스피커로 테스트 했다.


테스트는 영상으로 확인 하자.


반응형
Posted by J-sean
:
반응형

You can stream an audio file with MediaPlayer.


<AndroidManifest.xml>

1
    <uses-permission android:name="android.permission.INTERNET"/>



<MainActivity.java>

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
72
73
74
75
76
77
78
79
80
81
82
83
public class MainActivity extends AppCompatActivity {
 
    MediaPlayer mediaPlayer;
    int position = 0;
    boolean isPaused = false;   // To prevent false resume.
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // Play
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                if (mediaPlayer != null) {
                    mediaPlayer.release();
                }
                try {
                    mediaPlayer = new MediaPlayer();
                    mediaPlayer.setDataSource("http://nexoft.tk/download/Davich.mp3");  // or your audio file url.
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    isPaused = false;
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(), "Media player started", Toast.LENGTH_SHORT).show();
            }
        });
 
        // Stop
        Button button2 = findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    isPaused = false;
                    Toast.makeText(getApplicationContext(), "Media player stopped", Toast.LENGTH_SHORT).show();
                }
            }
        });
 
        // Pause
        Button button3 = findViewById(R.id.button3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    position = mediaPlayer.getCurrentPosition();
                    mediaPlayer.pause();
                    isPaused = true;
                    Toast.makeText(getApplicationContext(), "Media player paused at " + position / 1000 + " sec", Toast.LENGTH_SHORT).show();
                }
            }
        });
 
        // Resume
        Button button4 = findViewById(R.id.button4);
        button4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mediaPlayer != null && !mediaPlayer.isPlaying() && isPaused == true) {
                    mediaPlayer.start();
                    mediaPlayer.seekTo(position);
                    isPaused = false;
                    Toast.makeText(getApplicationContext(), "Media player resumed at " + position / 1000 + " sec", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
 
        if (mediaPlayer != null) {
            mediaPlayer.release();
        }
    }
}




Run the app and start the audio file.


반응형
Posted by J-sean
: