Форум программистов, компьютерный форум CyberForum.ru

сделать свою Beep() - C++

Восстановить пароль Регистрация
 
proef
0 / 0 / 0
Регистрация: 24.06.2013
Сообщений: 5
26.02.2014, 00:10     сделать свою Beep() #1
собственно как она реализуется ? может кто знает?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2014, 00:10     сделать свою Beep()
Посмотрите здесь:

как сделать свою формат-функцию? C++
C++ как сделать свою кнопку
C++ Beep() - музыка из динамика
Как сделать свою переменну в С++ C++
Как перехватить beep C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
school_bot
14 / 12 / 3
Регистрация: 23.12.2013
Сообщений: 84
26.02.2014, 06:01     сделать свою Beep() #2
в смысле системный звук?
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
27.02.2014, 22:00     сделать свою Beep() #3
да именно так
castaway
Эксперт С++
4837 / 2976 / 367
Регистрация: 10.11.2010
Сообщений: 11,008
Записей в блоге: 10
Завершенные тесты: 1
27.02.2014, 22:16     сделать свою Beep() #4
да, именно так и реализуется
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
27.02.2014, 23:46     сделать свою Beep() #5
я хотел бы посмотреть содержимое функции
Gepar
 Аватар для Gepar
1173 / 529 / 20
Регистрация: 01.07.2009
Сообщений: 3,508
28.02.2014, 02:01     сделать свою Beep() #6
Цитата Сообщение от proech Посмотреть сообщение
я хотел бы посмотреть содержимое функции
Оно примерно такое (наверное, исходников оригинальных нет ведь)
Кликните здесь для просмотра всего текста
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
class DSBeeper{
    LPDIRECTSOUNDBUFFER m_lpDSBuffer;
    LPDIRECTSOUND m_lpDS;
    DSBUFFERDESC dsbdesc;
    WAVEFORMATEX wfx;
 
    // These probably should not be changed
    static const INT32 MAX_FREQ = 32767;
    static const INT32 MIN_FREQ = 37;
    static const INT32 BITS_PER_SAMPLE = 16;
    static const INT32 NUM_CHANNELS = 1;
    static const INT32 SAMPLING_RATE = 44100;
    static const INT32 BUFFER_SIZE = SAMPLING_RATE * NUM_CHANNELS;
    static const INT32 SCALE = (1 << (BITS_PER_SAMPLE - 1))-1;
    // BUFFER_SIZE is just the maximum; it will not be used
 
    // Target frequency precision: less than 0.5% error
    //   37  Hz @ 44.1kHz sampling -> half-period of ~596 samples
    // 32.8 kHz @ 44.1kHz sampling -> half-period of ~0.67 samples
public:
    DSBeeper():m_lpDS(NULL){
        ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
        ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
 
        // All we do here is create the IDirectSound object
        if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))){
            return;
        }
        if(FAILED(DirectSoundCreate(NULL, &m_lpDS, NULL))){
            m_lpDS = NULL;
            return;
        }
        if(FAILED(m_lpDS->SetCooperativeLevel(GetDesktopWindow(),
                                              DSSCL_NORMAL))){
            m_lpDS->Release();
            m_lpDS = NULL;
            return;
        }
        
        // This won't change each to we call Beep(), so cache the values
        wfx.wFormatTag = WAVE_FORMAT_PCM;
        wfx.nChannels = NUM_CHANNELS;
        wfx.wBitsPerSample = BITS_PER_SAMPLE;
        wfx.nSamplesPerSec = SAMPLING_RATE;
        wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
        wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
        wfx.cbSize = 0;
        
        // Cache these values so we don't have to fill it in later
        dsbdesc.dwSize = sizeof(DSBUFFERDESC);
        dsbdesc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY
                        | DSBCAPS_CTRLFREQUENCY
                        | DSBCAPS_GLOBALFOCUS;
        dsbdesc.lpwfxFormat = &wfx;
    }
    ~DSBeeper(){
        if(NULL != m_lpDS){ m_lpDS->Release(); }
        CoUninitialize();
    }
    
    // This function fails silently; if parameters are out of bounds,
    // they are clamped to the bounds.
    // If DirectSound failed to initialize, returns FALSE.
    BOOL Beep(DWORD dwFreq, DWORD dwDuration){
        if(NULL == m_lpDS){ return FALSE; }
        
        // Clamp the frequency to the acceptable range
        if(dwFreq < MIN_FREQ){ dwFreq = MIN_FREQ; }
        if(dwFreq > MAX_FREQ){ dwFreq = MAX_FREQ; }
 
        // 1/dwFreq = period of wave, in seconds
        // SAMPLING_RATE / dwFreq = samples per wave-period
        INT32 half_period = SAMPLING_RATE * NUM_CHANNELS / (2*dwFreq);
        // The above line introduces roundoff error, which at higher
        // frequencies is significant (>30% at the 32kHz,
        // easily above 1% in general, not good). We will fix this below.
 
        // If frequency too high, make sure it's not just a constant DC level
        if(half_period < 1){ half_period = 1; }
        INT32 buffer_size = 2*half_period * BITS_PER_SAMPLE/8;
 
        // Make buffer
        dsbdesc.dwBufferBytes = buffer_size;
        if(FAILED(m_lpDS->CreateSoundBuffer(&dsbdesc, &m_lpDSBuffer, NULL))){
            return FALSE;
        }
 
        // Frequency adjustment to correct for the roundoff error above.
        DWORD play_freq;
        if(FAILED(m_lpDSBuffer->GetFrequency(&play_freq))){
            m_lpDSBuffer->Release();
            return FALSE;
        }
        // When we set the half_period above, we rounded down, so if
        // we play the buffer as is, it will sound higher frequency
        // than it ought to be.
        // To compensate, we should play the buffer at a slower speed.
        // The slowdown factor is precisely the rounded-down period
        // divided by the true period:
        //   half_period / [ SAMPLING_RATE * NUM_CHANNELS / (2*dwFreq) ]
        // = 2*dwFreq*half_period / (SAMPLING_RATE * NUM_CHANNELS)
        //
        // The adjusted frequency needs to be multiplied by this factor:
        //   play_freq *= 2*dwFreq*half_period / (SAMPLING_RATE * NUM_CHANNELS)
        // To do this computation (in a way that works on 32-bit machines),
        // we cannot multiply the numerator directly, since that may
        // cause rounding problems (44100 * 2*44100*1 ~ 3.9 billion which
        // is uncomfortable close to the upper limit of 4.3 billion).
        // Therefore, we use MulDiv to safely (and efficiently) avoid any
        // problems.
        play_freq = MulDiv(play_freq, 2*dwFreq*half_period,
                           SAMPLING_RATE * NUM_CHANNELS);
        if(FAILED(m_lpDSBuffer->SetFrequency(play_freq))){
            m_lpDSBuffer->Release();
            return FALSE;
        }
 
        // Write to buffer
        LPVOID lpvWrite;
        DWORD dwLen;
        if(SUCCEEDED(m_lpDSBuffer->Lock(0, buffer_size, &lpvWrite, &dwLen,
                                        NULL, NULL, DSBLOCK_ENTIREBUFFER))){
            buffer_int_t *p = (buffer_int_t*)lpvWrite;
 
            // Write in the square wave
            int i = half_period;
            while(i--){
                for(int j = 0; j < NUM_CHANNELS; ++j){
                    *p = -SCALE; p++;
                }
            }
            i = half_period;
            while(i--){
                for(int j = 0; j < NUM_CHANNELS; ++j){
                    *p = SCALE; p++;
                }
            }
 
            // Don't bother Sleeping if it didn't Play
            if(SUCCEEDED(m_lpDSBuffer->Unlock(lpvWrite, dwLen, NULL, NULL))){
                if(SUCCEEDED(m_lpDSBuffer->SetCurrentPosition(0))){
                    if(SUCCEEDED(m_lpDSBuffer->Play(0, 0, DSBPLAY_LOOPING))){
                        Sleep(dwDuration);
                        m_lpDSBuffer->Stop();
                    }
                }
            }
        }
 
        // Delete buffer
        if(NULL != m_lpDSBuffer){ m_lpDSBuffer->Release(); }
 
        return TRUE;
    }
};
Yandex
Объявления
28.02.2014, 02:01     сделать свою Beep()
Ответ Создать тему
Опции темы

Текущее время: 17:18. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru