purebasic.info

PureBasic forum
Текущее время: Пт янв 19, 2018 6:36 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 152 ]  На страницу Пред.  1 ... 7, 8, 9, 10, 11  След.
Автор Сообщение
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Ср сен 14, 2016 10:43 am 
Не в сети
профессор

Зарегистрирован: Вт мар 24, 2009 11:54 am
Сообщений: 354
Благодарил (а): 13 раз.
Поблагодарили: 18 раз.
Пункты репутации: 19
тоже были проблемы с циклическими щелчками. на буржуйском нашел как это победить
в коде посмотри там как раз реализован циклический буфер
http://purebasic.info/phpBB3ex/viewtopic.php?p=79343#p79343


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Ср сен 14, 2016 12:19 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
Спасибо, попробую разобраться.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Чт сен 15, 2016 2:50 am 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
Ну вот, благодаря вашим советам кажись закольцевал. :D Масив структур великоват но это на случай хорошего интернета. Мне немного неясен один момент: когда пишу данные каждый раз в новую структуру (wch(i)\lpData) то записывается ведь с начала адреса (который после AllocateMemory, например - 34734152), и каждая новая структура будет принимать данные именно с 34734152. Ибо память выделил один раз для всех структур в масиве. :shock: Не должно же оно писаться поверх данных (например: начало 34734152 +, скажем, 522 байта записано, следующая запись по адресу 34734152+522)?
Код:
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
InitNetwork()
 
#MPEGLAYER3_ID_MPEG = 1
#WAVE_FORMAT_MPEGLAYER3 = $ 0055
#MPEGLAYER3_WFX_EXTRA_BYTES = 12
#MP3_BLOCK_SIZE = 522
;--------------------------------------------------------------------------------------
Global phwo.l
Global Connection.l
Global *mem = AllocateMemory(65536)
;--------------------------------------------------------------------------------------
Global Dim wch.WAVEHDR(256)
For i = 0 To 255
  wch(i)\lpData = *mem
  wch(i)\dwBufferLength = 65536
  wch(i)\dwLoops = 0
  wch(i)\dwFlags = 0
Next i
;--------------------------------------------------------------------------------------
Structure MPEGLAYER3WAVEFORMAT
  WFX.WAVEFORMATEX
  WID.w
  fdwFlags.l
  nBlockSize.w
  nFramesPerBlock.w
  nCodecDelay.w
EndStructure  : mpe.MPEGLAYER3WAVEFORMAT
 
mpe\WFX\wFormatTag = #WAVE_FORMAT_MPEGLAYER3
mpe\WFX\nChannels = 2
mpe\WFX\nSamplesPerSec = 44100
mpe\WFX\nAvgBytesPerSec = 128 * (1024 / 8)
mpe\WFX\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES
mpe\WID = #MPEGLAYER3_ID_MPEG
mpe\nBlockSize = #MP3_BLOCK_SIZE
;--------------------------------------------------------------------------------------
Procedure waveOutProc(HWO.l, uMsg.l, dwInstance.l, *dwParam1.WAVEHDR, dwParam2.l)
  Select uMsg
    Case #WOM_OPEN
      ;Debug "WOM_OPEN"
    Case #WOM_DONE
      ;Debug "WOM_DONE"
    Case #WOM_CLOSE
      ;Debug "WOM_CLOSE"
  EndSelect    
  ProcedureReturn
EndProcedure
;--------------------------------------------------------------------------------------
Procedure play(*p)
  Protected i.l = 0
  Repeat
    Delay(1)
   
    wch(i)\dwBufferLength = ReceiveNetworkData(Connection, wch(i)\lpData, 65536)
    waveOutWrite_(phwo, @wch(i), SizeOf(WAVEHDR))
    i + 1 : If i = 255 : i = 0 : EndIf
   
  ForEver
EndProcedure
;--------------------------------------------------------------------------------------
waveOutOpen.l = waveOutOpen_(@phwo, #WAVE_MAPPER, @mpe, @waveOutProc(), 0, #CALLBACK_FUNCTION)
If waveOutOpen = 0
  For i = 0 To 255
    waveOutPrepareHeader_(phwo, @wch(i), SizeOf(WAVEHDR))
  Next i
EndIf  
;--------------------------------------------------------------------------------------
Connection = OpenNetworkConnection("beelinefm.hostingradio.ru", 8058, #PB_Network_TCP)
get.s = "GET /beeline128.mp3 HTTP/1.1"  + #CRLF$
get = get + "Host: beelinefm.hostingradio.ru"  + #CRLF$
get = get + "User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 OPR/35.0.2066.37" + #CRLF$
get = get + #CRLF$
SendNetworkData(Connection, @get, Len(get))
CreateThread(@play(), 0)
;--------------------------------------------------------------------------------------
Repeat
  Delay(1)
ForEver



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Пт сен 16, 2016 2:29 pm 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 27
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
repeat писал(а):
Ну вот, благодаря вашим советам кажись закольцевал. :D Масив структур великоват но это на случай хорошего интернета. Мне немного неясен один момент: когда пишу данные каждый раз в новую структуру (wch(i)\lpData) то записывается ведь с начала адреса (который после AllocateMemory, например - 34734152), и каждая новая структура будет принимать данные именно с 34734152. Ибо память выделил один раз для всех структур в масиве. :shock: Не должно же оно писаться поверх данных (например: начало 34734152 +, скажем, 522 байта записано, следующая запись по адресу 34734152+522)?

Во-первых, крайне желательно сразу же избавиться от магических чисел как в коде, так и в рассуждениях. Всякие вот эти 34734152, Delay(1) и ReceiveNetworkData(Connection, wch(i)\lpData, 65536) - в один прекрасный момент вам захочется уменьшить или увеличить буфер в AllocateMemory, а внести изменения в остальном коде вы обязательно забудете. Не в этой программе, так в следующей. И гораздо проще обсуждать хотя бы *mem, а еще лучше *MP3buffer или вроде того, чем какие-то там 34734152.

Во-вторых, что вы считаете "кольцевым буфером", на самом деле таковым не является. У вас выделяется один буфер размером 64К, и каждый член массива wch() указывает на него. С тем же успехом вместо wch.WAVEHDR(256) можно использовать wch.WAVEHDR. По-настоящему кольцевым он станет только если выделить, скажем, буфер размером 256*64К и при инициализации назначить указателям на его фрагменты РАЗЛИЧНЫЕ адреса wch(i)\lpData = *mem + 65536*i (магическое число чисто для примера, использовать его в таком виде, опять-таки, не следует). Тут еще следует заметить, что такой объем буфера представляется, мягко говоря, избыточным. 16Мб буфер - это где-то четверть часа звучания 128кб потока MP3. Настолько огромный буфер не нужен ни при "хорошем", ни при "плохом" интернете. По мне так минуты-две достаточно за глаза.

В-третьих, получение данных и их воспроизведение надо разнести и подгружать данные в буфер по мере их проигрывания "вперед". То есть, должно быть ДВА указателя на элементы массива wch: один указывает на тот блок памяти, который проигрывается в настоящее время, и другой - на текущий блок памяти для предварительной подкачки потоковых данных. Как только проиграли 1-2-N блоков, начали загрузку блока(блоков), которые будут играть еще через несколько блоков, т.е. с некоторым опережением.

Есть еще в-четвертых, в-пятых и так далее, но перечисленные пункты концептуальны.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Пт сен 16, 2016 2:55 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
puric писал(а):
Во-первых, крайне желательно сразу же избавиться от магических чисел как в коде, так и в рассуждениях. Всякие вот эти 34734152, Delay(1) и ReceiveNetworkData(Connection, wch(i)\lpData, 65536) - в один прекрасный момент вам захочется уменьшить или увеличить буфер в AllocateMemory, а внести изменения в остальном коде вы обязательно забудете. Не в этой программе, так в следующей. И гораздо проще обсуждать хотя бы *mem, а еще лучше *MP3buffer или вроде того, чем какие-то там 34734152.
Согласен, хотя подсветка синтаксиса очень даже выручает :D
Цитата:
Во-вторых, что вы считаете "кольцевым буфером", на самом деле таковым не является. У вас выделяется один буфер размером 64К, и каждый член массива wch() указывает на него. С тем же успехом вместо wch.WAVEHDR(256) можно использовать wch.WAVEHDR.
Для одного буфера да, но как закольцевать wch.WAVEHDR?
Цитата:
В-третьих, получение данных и их воспроизведение надо разнести и подгружать данные в буфер по мере их проигрывания "вперед".
waveOutWrite не воспроизводит данные а ставит в очередь.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Пт сен 16, 2016 4:44 pm 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 27
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
repeat писал(а):
waveOutWrite не воспроизводит данные а ставит в очередь.

MSDN утверждает, что эта функция отправляет блок данных устройству вывода. Я буду считать, что это равнозначно проигрыванию, вы можете считать, что данные лишь ставятся в очередь. Это все неважно.

repeat писал(а):
Для одного буфера да, но как закольцевать wch.WAVEHDR?

После проигрывания текущего фрагмента (программа получает соответствующее уведомление от операционной системы) мы должны приступить к воспроизведению / поставить в очередь / отправить на устройство (нужное подчеркнуть) следующий фрагмент, который к этому времени должен лежать в блоке буфера, на который указывает wch(CurrentBlock) и параллельно начать качать новый кусок потока.

Для простоты допустим, что буфер состоит из двух блоков, на которые указывают wch(0) и wch(1) и оба они заполнены данными для воспроизведения.

1. Начинаем проигрывать: CurrentBlock = 0 : waveOutWrite_(phwo, @wch(CurrentBlock), SizeOf(WAVEHDR))
2. Ловим #WOM_DONE или #MM_WOM_DONE - это сигнал того, что текущий фрагмент проигран и надо начать проигрывание следующего: CurrentBlock = 1 : waveOutWrite_(phwo, @wch(CurrentBlock), SizeOf(WAVEHDR)) Качаем следующий фрагмент в wch(0). Лучше асинхронно, через отдельный поток и семафоры.
3. Ловим #WOM_DONE или #MM_WOM_DONE - воспроизводим wch(0), качаем в wch(1)
...

Кольцевым буфером это назвать сложно, а вот буфер на три фрагмента будет вполне себе кольцевым.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Пт сен 16, 2016 5:52 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
Оно то так, только нужно синхронизировать ReceiveNetworkData с waveOutWrite, иначе или задыхается или захлебывается. А когда массив большой, то можно записывать не задумываясь что перезапишет. А на счет очереди легко проверить поставив Debug на #WOM_DONE и waveOutWrite :D


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Пт сен 16, 2016 8:26 pm 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 27
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Да нельзя не задумываться, нельзя использовать единственный буфер одновременно для записи новой порции потока и для воспроизведения ранее принятых данных. Буфер можно считать доступным для записи только после получения соответствующего уведомления. Пока он не освободился, писать в него нельзя. Это не моя блажь, так велит MSDN.

Далее. В вашем примере звуковой поток будет "потребляться" устройством вывода со скоростью 128 кбит в секунду. А с сервера он запросто сможет качаться со скоростью в несколько десятков мегабит в секунду. Вы просто моментально забьете буфер устройства вывода. Без синхронизации у вас получится полная хрень.

Исходя из вышеизложенного, настоятельно рекомендуются минимум два буфера с переключением между ними и синхронизация скачивания и воспроизведения.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Пт сен 16, 2016 9:21 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11080
Благодарил (а): 4 раз.
Поблагодарили: 385 раз.
По моему неправильно задан формат. Этот код должен несколько секунд нормально воспроизводить музыку, но вместо этого "дерганое" пение.
Код:
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
InitNetwork()
 
#MPEGLAYER3_ID_MPEG = 1
#WAVE_FORMAT_MPEGLAYER3 = $ 0055
#MPEGLAYER3_WFX_EXTRA_BYTES = 12
#MP3_BLOCK_SIZE = 522
;--------------------------------------------------------------------------------------
Global phwo.l
Global Connection.l
Global *mem = AllocateMemory(65536)
;--------------------------------------------------------------------------------------
Global wch.WAVEHDR
wch\lpData = *mem
wch\dwBufferLength = MemorySize(*mem)
wch\dwLoops = 0
wch\dwFlags = 0
;--------------------------------------------------------------------------------------
Structure MPEGLAYER3WAVEFORMAT
  WFX.WAVEFORMATEX
  WID.w
  fdwFlags.l
  nBlockSize.w
  nFramesPerBlock.w
  nCodecDelay.w
EndStructure  : mpe.MPEGLAYER3WAVEFORMAT
 
mpe\WFX\wFormatTag = #WAVE_FORMAT_MPEGLAYER3
mpe\WFX\nChannels = 2
mpe\WFX\nSamplesPerSec = 44100
mpe\WFX\nAvgBytesPerSec = 128 * (1024 / 8)
mpe\WFX\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES
mpe\WID = #MPEGLAYER3_ID_MPEG
mpe\nBlockSize = #MP3_BLOCK_SIZE
;--------------------------------------------------------------------------------------
Procedure waveOutProc(HWO.l, uMsg.l, dwInstance.l, *dwParam1.WAVEHDR, dwParam2.l)
  Select uMsg
    Case #WOM_OPEN
      ;Debug "WOM_OPEN"
    Case #WOM_DONE
      ;Debug "WOM_DONE"
    Case #WOM_CLOSE
      ;Debug "WOM_CLOSE"
  EndSelect    
  ProcedureReturn
EndProcedure
;--------------------------------------------------------------------------------------
Procedure play(*p)
  Repeat
    Delay(10000)
    Debug "Play 1"
    wch\dwBufferLength = ReceiveNetworkData(Connection, wch\lpData, 65536)
    Debug "Play 2"
    waveOutWrite_(phwo, @wch, SizeOf(WAVEHDR))
    Debug "Play 3"
    While wch\dwFlags = 18
    Wend
    Debug "Play 4"
  ForEver
EndProcedure
;--------------------------------------------------------------------------------------
waveOutOpen.l = waveOutOpen_(@phwo, #WAVE_MAPPER, @mpe, @waveOutProc(), 0, #CALLBACK_FUNCTION)
If waveOutOpen = 0
  waveOutPrepareHeader_(phwo, @wch, SizeOf(WAVEHDR))
EndIf  
;--------------------------------------------------------------------------------------
Connection = OpenNetworkConnection("beelinefm.hostingradio.ru", 8058, #PB_Network_TCP)
get.s = "GET /beeline128.mp3 HTTP/1.1"  + #CRLF$
get = get + "Host: beelinefm.hostingradio.ru"  + #CRLF$
get = get + "User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36 OPR/35.0.2066.37" + #CRLF$
get = get + #CRLF$
SendNetworkData(Connection, @get, Len(get))
CreateThread(@play(), 0)
waveOutWrite_(phwo, @wch, SizeOf(WAVEHDR))
;--------------------------------------------------------------------------------------
Repeat
  Delay(1)
ForEver


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Сб сен 17, 2016 3:35 am 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
puric писал(а):
Исходя из вышеизложенного, настоятельно рекомендуются минимум два буфера с переключением между ними и синхронизация скачивания и воспроизведения.
Согласен. :?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Сб сен 17, 2016 3:42 am 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
Пётр писал(а):
По моему неправильно задан формат. Этот код должен несколько секунд нормально воспроизводить мызыку, но вместо этого "дерганое" пение.
Все может быть, данные то приходят
Код:
1
2
3
4
25176 
26910
27740
26280

порядочного размера а играет всего ничего. :roll:

Но ведь играет :shock:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Сб сен 17, 2016 8:53 pm 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1576
Откуда: Алматы
Благодарил (а): 12 раз.
Поблагодарили: 39 раз.
Пункты репутации: 5
а ты подобный код смотрел? тут как раз организация звучания. я вот думаю если разберусь - это значит тоже можно будет басс.длл мне выкинуть :) пока чот ничерта у меня не поет мой сраный процессор звуковой :)

Код:
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
; ********************************************************************************
; Sound Generator - A stereo sound generator with independent channel controls and a few
;                   extra features.
; (c)2013 of the author RichardL.
; Free to copy, use or ignore!
; 1.1 Put on PB website 13:55 21st April 2013
; 1.2 22nd April 2013
;     Changed to ScrollBar()s - Nicer behaved. Added horizontal grid lines - Looks better!
;     Added Y 'scope sliders. Re-styled lots of code. Temporary  mono WAV player
;     on Left channel... which 'works' if you can find a 16 bit mono PCM WAV file.
; 1.3 23rd April 2013
;     'Scope now triggered by Right channel when Left is Off.
;     Output level now Zero when Off, was constant at full negative.
;     Correction to WAVPath$ after a file is selected
 
; ********************************************************************************
 
Declare WinCallback(hwnd, uMsg, wParam, lParam)  ;- Window callback
Declare Thread_CalcWave(Z)                       ;- Calculate the waveform for left / right channels
 
Global BLKSIZE, hSound, Channels, BytesPerSample,BufSize
Global LockLR, LockOffset
Global ThreadID,ScopeImage
Global La.f, Ra.f , DoDP, DoDF
Global hWAV
WAVPath$ = "C:\Temp\"
 
#PIx2 = #PI * 2
 
Enumeration 1000 ; Windows, Gadgets, Hot keys
  #Win_SNDWin
 
  #Gad_Scope  
  #Gad_WavL    
  #Gad_WavR    
  #Gad_SwitchL
  #Gad_SwitchR
  #Gad_FreqL  
  #Gad_FreqR  
  #Gad_VolumeL  
  #Gad_VolumeR  
  #Gad_Lock    
  #Gad_LockOfs  
  #Gad_SwitchDF
  #Gad_SwitchDP
  #Gad_PlayWAV
  #Gad_LeftY
  #Gad_RightY
EndEnumeration
Structure Waves
  WaveForm.i
  Frequency.i
  Volume.f
  Switch.i
  YPos.i
EndStructure
Global left.Waves
Global right.Waves
 
;{- Control panel
ScopeImage = CreateImage(#PB_Any,512,256)
; Buttons etc.
OpenWindow(#Win_SNDWin,0,0,600,400,"Sound Generator - R1.3 (c) RichardL 2013",#PB_Window_SystemMenu |#PB_Window_ScreenCentered)
ImageGadget(#Gad_Scope,41,10,512+6,256+6,ImageID(ScopeImage),#PB_Image_Border)
ScrollBarGadget(#Gad_LeftY,28,4,10,269,0,256,1,#PB_ScrollBar_Vertical)
ScrollBarGadget(#Gad_RightY,512+47,4,10,269,0,256,1,#PB_ScrollBar_Vertical)
ComboBoxGadget(#Gad_WavL,44,276,80,20)
ComboBoxGadget(#Gad_WavR,356,276,80,20)
CheckBoxGadget(#Gad_SwitchL,164, 276,80, 20,"Left On/Off")
CheckBoxGadget(#Gad_SwitchR,474,276,80,20,"Right On/Off",#PB_CheckBox_Right)
TextGadget(#PB_Any,244,306,110,20,"Frequency",#PB_Text_Center)
ScrollBarGadget(#Gad_FreqL,44, 306,200,20,35,8000,1)
ScrollBarGadget(#Gad_FreqR,356,306,200,20,35,8000,1)
TextGadget(#PB_Any,244,336,110,20,"Amplitude",#PB_Text_Center)
ScrollBarGadget(#Gad_VolumeL,44 ,336,200,20,0,100,1)
ScrollBarGadget(#Gad_VolumeR,356,336,200,20,0,100,1)
CheckBoxGadget(#Gad_Lock,44,366,80,20,"Lock L+R")
StringGadget(#Gad_LockOfs,134,366,60,20,"0", #PB_String_Numeric)
OptionGadget(#Gad_SwitchDF,204,358,100,20,"Freq offset (Hz)")
OptionGadget(#Gad_SwitchDP,204,379,110,20,"Phase offset (Deg)")
ButtonGadget(#Gad_PlayWAV,356,366,200,20,"Play WAV")
 
; Waveform choices
WaveType$ = "Sine|Square|Sawtooth|Noise|WAV File|"
For n = 1 To CountString(WaveType$,"|")
  AddGadgetItem(#Gad_WavL,-1,StringField(WaveType$,n,"|"))
  AddGadgetItem(#Gad_WavR,-1,StringField(WaveType$,n,"|"))
Next
 
; Initial frequencies etc
With left           ; 1000 Hz Sinewave on left, On
  \Frequency = 1000
  \Volume    = 0.2
  \Switch    = #True
  \WaveForm  = 0
  \YPos      = 127
EndWith
With right
  \Frequency = 300    ; 300 Hz Sinewave on right, Off
  \Volume    = 0.2
  \Switch    = #False
  \WaveForm  = 0
  \YPos      = 127
EndWith
 
LockLR     = #False   ; Option to lock RIGHT frequency to LEFT frequency (With frequency or phase offset.)
DoDF       = #True    ; When L&R frequencies are BOTH controlled by the LEFT channel there is an
DoDP       = #False   ; option for having a phase or frequency offset.
 
; Set controls to match initial conditions
SetGadgetState(#Gad_FreqL,left\Frequency/2)  : SetGadgetState(#Gad_VolumeL,100*left\Volume) : SetGadgetState(#Gad_SwitchL,left\Switch)
SetGadgetState(#Gad_FreqR,right\Frequency/2) : SetGadgetState(#Gad_VolumeR,100*right\Volume): SetGadgetState(#Gad_SwitchR,right\Switch)
SetGadgetState(#Gad_WavL,left\WaveForm)    : SetGadgetState(#Gad_WavR,right\WaveForm)
 
SetGadgetState(#Gad_Lock,LockLR)
SetGadgetState(#Gad_SwitchDF,DoDF) : SetGadgetState(#Gad_SwitchDP,DoDP)
DisableGadget(#Gad_PlayWAV,#True)
 
SetGadgetState(#Gad_LeftY, left\YPos)
SetGadgetState(#Gad_RightY,right\YPos)
 
; Create a backdrop for the oscilloscope with 1mSec grid lines
StartDrawing(ImageOutput(ScopeImage))
  FrontColor($0089C89)
  X = 0
  f.f = 512/(1000*2048/(44100*4)) ; Scale factor for 1 mSec grid
  While X <512
    LineXY(X,0,X,255)
    X + f.f
  Wend
  Y = 0  ; Horizontal lines are purely cosmetic!
  While Y < 128
    LineXY(0,128-Y,512,128-Y)
    LineXY(0,128+Y,512,128+Y)
    Y + f.f
  Wend
StopDrawing()
SetGadgetState(#Gad_Scope,ImageID(ScopeImage))
;}
;{- Prep and start
;{ Create stereo sound header plus buffer
; http://www.sonicspot.com/guide/wavefiles.html#fact        Useful item about the WAV/RIFF header...
 
; Sound replay
CAPTURECLOCK   = 44100                                      ; Sampling/Replay frequency in 'samples per second'
BLKSIZE        = 2048                                       ; Number of samples in capture/play block
BytesPerSample = 2                                          ; Number of bytes needed for each sample
Channels       = 2                                          ; Number of channels, 1 for mono, 2 for stereo.
BufSize        =  (BytesPerSample * Channels * BLKSIZE * 2) ; Buffer to hold TWO blocks
*Header        =  AllocateMemory(BufSize + 12 + 16 + 8)     ; Memory for header and buffer
*P = *Header
 
; 'RIFF' chunk descriptor - 12 bytes
PokeS(*P,"RIFF",4)                          : *P + 4        ; 00-03 Chunk ID                                     4
PokeL(*P,0)                                 : *P + 4        ; 04-07 Chunk data size (Place holder)               4
PokeS(*P,"WAVE",4)                          : *P + 4        ; 08-11 'RIFF type'                                  4
 
; 'fmt' Subchunk          - 16 bytes
PokeS(*P,"fmt ",4)                          : *P+ 4         ; 12-15 'SubChunk ID'
PokeL(*P,16)                                : *P+ 4         ; 16-19 'Chunk data size'
*Q=*P
PokeW(*P,1)                                 : *P+ 2         ; 20-21 'Compression code' 1=Non-compressed data PCM  2
PokeW(*P,2)                                 : *P+ 2         ; 22-24 'Number of channels'                          2
PokeL(*P,CAPTURECLOCK)                      : *P+ 4         ; 24-27 'Sample rate'                                 4
PokeL(*P,Channels * BytesPerSample * CAPTURECLOCK) : *P+ 4  ; 28-31 'Average bytes per second'                    4
PokeW(*P,BytesPerSample * Channels)         : *P+ 2         ; 32-33 'Block align' Bytes per sample slice          2
PokeW(*P,8 * BytesPerSample )               : *P+ 2         ; 34-35 'Significant bits per sample'                 2
 
; 'data' Subchunk          - 8 bytes (+Buffer)
PokeS(*P,"data",4)                          : *P + 4        ; 'SubChunk ID'                                      4
PokeL(*P,BufSize)                           : *P + 4        ; Length of my data                                  4
FillMemory(*P,BufSize,0,#PB_Word)                           ; Clear the buffer
;}
If InitSound()= 0                                           ; Initialise sound environment
  MessageRequester("ERROR","Cannot initialise sound resources")
  End
EndIf
hSound = CatchSound(#PB_Any,*Header)                        ; Set up a sound    
PlaySound(hSound, #PB_Sound_Loop)                           ; Start playing the buffer
ThreadID = CreateThread(@Thread_CalcWave(),1)               ; Start generating waveform in *Buf
SetWindowCallback(@WinCallback())                           ; Callback used to manage the slider controls
;}
;{- Dispatch
Finish = #False
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow        ;{ Close window
      Finish = #True
      ;}
    Case #PB_Event_Gadget             ;{ Buttons and gadgets
      Select EventGadget()
         
        Case #Gad_SwitchL : left\Switch  = GetGadgetState(#Gad_SwitchL)
        Case #Gad_SwitchR : right\Switch = GetGadgetState(#Gad_SwitchR)
         
        Case #Gad_Lock
          LockLR = GetGadgetState(#Gad_Lock)
          DisableGadget(#Gad_FreqR,LockLR)
          If LockLR = #False
            right\Frequency = GetGadgetState(#Gad_FreqR)
          Else
            La.f = Ra.f + 3.142
          EndIf
         
        Case #Gad_SwitchDF, #Gad_SwitchDP
          DoDF = GetGadgetState(#Gad_SwitchDF)    ; A flip-flop pair
          DoDP = DoFR ! 1
         
        Case #Gad_WavL
          left\WaveForm = GetGadgetState(#Gad_WavL)
          If left\WaveForm = 4
            WAVFile$ = OpenFileRequester("Load a WAV File",WAVPath$,"WAV Files|*.WAV",0)
            If WAVFile$
              WAVPath$ = GetPathPart(WAVFile$)
              DisableGadget(#Gad_PlayWAV,#False)
              SetGadgetText(#Gad_PlayWAV,"Play<"+GetFilePart(WAVFile$)+">")
              EndIf
          EndIf
         
        Case #Gad_WavR
          right\WaveForm = GetGadgetState(#Gad_WavR)
         
        Case #Gad_PlayWAV ; Kludge to play a 16bit Mono 44.1K sampple rate WAV file
          ; No header checks, no nuffin'
          If IsFile(hWAV) : CloseFile(hWAV) : hWAV = 0 : EndIf
          If WAVFile$
            hWAV  = OpenFile(#PB_Any,WAVFile$)
            FileSeek(hWAV,36)
          EndIf
         
      EndSelect
  EndSelect
  ;}
    If EventType() =  #PB_EventType_Change
      If EventGadget() = #Gad_LockOfs
        LockOffset = Val(GetGadgetText(#Gad_LockOfs))
      EndIf
    EndIf
   
Until Finish
;}
;{- PUFO
ThreadID = 0
Delay(50)
StopSound(hSound)
;}
End
Procedure WinCallback(hwnd, uMsg, wParam, lParam) ;- Window callback to service frequqncy and volume sliders
  Select uMsg
    Case  #WM_HSCROLL
      ; Two frequency and two amplitude controls
      Select lParam
        Case GadgetID(#Gad_FreqL)   : left\Frequency  = GetGadgetState(#Gad_FreqL)*2         ; Frequency value directly from control
        Case GadgetID(#Gad_FreqR)   : right\Frequency = GetGadgetState(#Gad_FreqR)*2
        Case GadgetID(#Gad_VolumeL) : left\Volume     = GetGadgetState(#Gad_VolumeL) / 100 ; Scale over range 0 to 1. FLOAT
        Case GadgetID(#Gad_VolumeR) : right\Volume    = GetGadgetState(#Gad_VolumeR) / 100
      EndSelect
     
      ; Set 'Scope Y positions
    Case #WM_VSCROLL
      Select lParam
        Case GadgetID(#Gad_LeftY)   : left\YPos       = GetGadgetState(#Gad_LeftY)
        Case GadgetID(#Gad_RightY)  : right\YPos      = GetGadgetState(#Gad_RightY)
      EndSelect
       
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure Thread_CalcWave(Z)                      ;- Calculate the waveform for left / right channels
  ; This thread  generates the left and right waveforms for the play buffer <<continually>>.
  ; Both channels are phase continuous.
 
  ; Left and right samples are interleaved and each sample is a WORD value. (L.w, R.w, L.w, R.w, L.w, R.w.... etc
  ; The thread needs to complete writing half a buffer before Windows finished playing the other half.
 
  ; The buffer contains 2048 * 2 samples that are played at 44100 samples persecond so it takes 2048/44100 seconds to
  ; play half the buffer, 46.4 milliseconds. This code needs to complete it's function in less than this time.
 
  Protected Angle.f,Vl.f,Vr.f,Kl.f,Kr.f,LastVL.f,LastVR.f
  Protected X,Yl,Yr,OldX,OldYL,OldYR
  Protected Fill_1,fill_2,*P,*K
  Protected Trig = BLKSIZE                      ; Half of our buffer
  Protected Ptr1,Bytes1,Ptr2,Bytes2
 
  ; http://msdn.microsoft.com/en-gb/library/windows/desktop/microsoft.directx_sdk.idirectsoundbuffer8.idirectsoundbuffer8.lock(v=vs.85).aspx
  DS.IDirectSoundBuffer = PeekL(IsSound(hSound))
 
  ; Safe GetSoundPosition() windows when we can write to the buffer.
  ; (Draw a circle with a circumference of BLKSIZE*2 units...)
  Dim StartWin(1) : Dim EndWin(1) : Dim BasePos(1)
  StartWin(0) = 768  : StartWin(1) = 2816 : BasePos(0) = BLKSIZE*4 ;(4? two channels of WORD samples)
  EndWin(0)   = 1280 : EndWin(1)   = 3328 : BasePos(1) = 0
  Flip = 0
 
  While ThreadID
   
    ;{ Calculate the frequency scaling factors - Provisional...
    Kl = left\Frequency / (44100/#PIx2)
    If LockLR                                  ; If channels are locked together, there are two lock modes...
      If DoDF                                  ; (1) With a user specified frequency offset...
        right\Frequency = left\Frequency + LockOffset
      Else                                     ; (2) With a phase offest...
        right\Frequency = left\Frequency
        Ra = La + (LockOffset/360) * #PIx2
      EndIf
     
    EndIf
    Kr = right\Frequency /(44100/#PIx2)
    ;}
   
    ; Find which half of the buffer are we currently playing and make write pointer to the other.
    ; (GetSoundPosition() takes about 4 uS and Sinewave creation takes about  120 uS on my machine
    ; which is more that fast enough.)
    ; The following simple method 'works' but is not as elegant as using the DirectX
    ; 'SetNotificationPositions' style of solution.
   
    Position =  GetSoundPosition(hSound)                          ; Current play position...
    If Position > StartWin(Flip) And Position < EndWin(Flip)      ;
      Flip ! 1
      Base = BasePos(Flip)
      Flag   = #True
    EndIf
   
    ;{/ Write waveform data to half the buffer
    If Flag                                                         ; If we are fill are to fill part of the buffer...
      If DS\Lock(Base,BLKSIZE,@Ptr1,@Bytes1,@Ptr2,@Bytes2,0) = 0    ; Get address of block to be written
       
        *P = Ptr1
        *K = Ptr1
       
        For n = 0 To BLKSIZE - 1
         
          ; Derive LEFT channel waveform points.
          ;(Being more rigorous by using Round() etc made no difference to the glitches)
          If left\Switch                        ; If Left channel is switched ON...
            Select left\WaveForm
              Case 0 : Vl = Sin(La) * 32767 * left\Volume          ; SineWave
              Case 1 : Vl = 32767 * left\Volume                    ; Square
                If La>#PI : Vl = -Vl : EndIf
              Case 2 : Vl = 32767 * left\Volume * (La-#PI)/#PI     ; Sawtooth
              Case 3 : Vl = (Random(65535)-32768) * left\Volume   ; Noise
              Case 4
                  If hWAV And Not Eof(hWAV)
                    Vl = ReadWord(hWAV) * left\Volume
                  Else
                    If hWAV : CloseFile(hWAV) : hWAV = 0 : EndIf
                    Vl = 0
                  EndIf
               
            EndSelect
            La + Kl                                                ; Calculate angle for next time
            If La > #PIx2 : La - #PIx2 : EndIf                     ; limit to 2*PI radians
          Else                                                     ; Not ON so point is zero
            Vl = 0
          EndIf
          PokeW(*P,Vl)                                             ; Put point in buffer
          *P + BytesPerSample                                      ; move buffer pointer to next RIGHT sample
         
          ; Derive RIGHT channel waveform point
          If right\Switch
            Select right\WaveForm
              Case 0 : Vr = Sin(Ra) * 32767 * right\Volume        
              Case 1 : Vr = 32767 * right\Volume
                If Ra>#PI : Vr = -Vr : EndIf                      
              Case 2 : Vr = 32767 * right\Volume * (Ra-#PI)/#PI    
              Case 3 : Vr = (Random(65535)-32768) * right\Volume  
            EndSelect
            Ra + Kr
            If Ra > #PIx2 : Ra - #PIx2 : EndIf
          Else
            Vr = 0
          EndIf
          PokeW(*P,Vr)
          *P + BytesPerSample
         
        Next
       
        T = DS\UnLock(Ptr1,Bytes1,Ptr2,Bytes2)
        ;If T : Debug Ptr1 :EndIf
      EndIf
       
      ;}
      ;{/ Draw the oscilloscope display
      *P = *K
      Copy = CopyImage(ScopeImage,#PB_Any)     ; Make temporary copy of 'scope backdrop
      StartDrawing(ImageOutput(Copy))
       
        ; Show the two channel frequencies
        DrawText(8,8,Str(left\Frequency)+" Hz",#Red)
        DrawText(450,8,Str(right\Frequency)+" Hz",#Green)
         
        LastVL = 1000 :  STrig = 0            ; Prime the trigger
        X = 0
        For n = 0 To BLKSIZE-1
         
          ; Get the left and right signal levels
          Vl = PeekW(*P) : *P + 2              
          Vr = PeekW(*P) : *P + 2
         
          ; Detect positive zero-crossing on left channel to trigger the 'scope
          If left\Switch
            If (LastVL <= 0) And (Vl > 0)        ; Rising though zero?
              STrig = #True                      ; Set trigger flag...
            EndIf                                
            LastVL = Vl                          ; Keep current Left value to compare with next
          Else                                   ; If Left channel OFF then trigger from Right...
            If (LastVR <= 0) And (Vr > 0)        ; Rising though zero?
              STrig = #True                      ; Set trigger flag...
            EndIf                                
            LastVR = Vr                          ; Keep current Left value to compare with next
          EndIf
         
          ; Plot scope display of first 512 points after a Left zero crossing
          ; (NB: Using Round() would be better than Int()...)
          If (X < 512) And STrig
            Yl = left\YPos - Int(Vl)>>8        ; Scale and offset the LEFT waveform ('-' makes positive = up)
            Yr = right\YPos- Int(Vr)>>8        ; Scale and offset the RIGHT waveform
            If X                               ; After the first point...
              LineXY(OldX,OldYL,X,Yl,#Red)     ; join to previous point
              LineXY(OldX,OldYR,X,Yr,#Green)
            EndIf
            OldX  = X                          ; Keep values to become the previous, next time
            OldYL = Yl
            OldYR = Yr
            X + 1
          EndIf
         
        Next
       
      StopDrawing()
      SetGadgetState(#Gad_Scope, ImageID(Copy)) ; Transfer the new display to the display gadget
      FreeImage(Copy)                          ; Dispense with temporary image
      ;}
      Flag =#False
     
    EndIf
    Delay(3)
   
  Wend
EndProcedure



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Вс сен 18, 2016 4:41 am 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
Сделать урезанный аналог bass'a было бы милое дело. По сути с bass.dll каждому нужно не более 10 функций (за исключением каких-нибудь грандиозных проектов). И за эти несколько функций нужно втюхать больше чем за среду разработки в которой их используешь. :shock: И это при том, что в windows уже имеется все необходимое. Вот ресурс, кажись все по полочкам, а не работает ни в какую. Хорошо бы еще разобраться с типами "WORD и DWORD". Смотрю справку:

Word .w 2 bytes -32768 to +32767 попутно -16-bit unsigned integer. The range is 0 through 65535 decimal.Так это - .u :?: .c :?:

DWORD - 32-bit unsigned integer. The range is 0 through 4294967295 decimal. Предполагаю это .f :?:
SereZa писал(а):
а ты подобный код смотрел? тут как раз организация звучания
У меня не звучит :shock:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Вс сен 18, 2016 9:41 am 
Не в сети
профессор

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1576
Откуда: Алматы
Благодарил (а): 12 раз.
Поблагодарили: 39 раз.
Пункты репутации: 5
эм... вот жеж блин :) а у меня хр и все поет (а галки юникода и тредсейф в настройках стоят?). точнее пищит :) генератор частоты или кто он там...

вот другой, но тут по моему комментариев меньше:
Код:
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
156
157
158
Enumeration
  #Window_0
EndEnumeration
 
;{ Gadgets
Enumeration
  #TrackBarGadget_1
  #ButtonGadget_2
  #ButtonGadget_3
  #TextGadget_0
EndEnumeration
;}
;{ Fonts
Enumeration
  #Font_TextGadget_0
EndEnumeration
;}
 
Structure WAVE
  wFormatTag.w
  nChannels.w
  nSamplesPerSec.l
  nAvgBytesPerSec.l
  nBlockAlign.w
  wBitsPerSample.w
  cbSize.w
EndStructure
 
Procedure MakeSound(nr,Frequency, duration);
  SoundValue.b
  w.f; // omega ( 2 * pi * frequency)
  #Mono= $0001;
  #SampleRate= 44100; // 8000, 11025, 22050, or 44100
  #RiffId = "RIFF";
  #WaveId=  "WAVE";
  #FmtId=   "fmt ";
  #DataId=  "data";
 
  WaveFormatEx.WAVE
  WaveFormatEx\wFormatTag=#WAVE_FORMAT_PCM;
  WaveFormatEx\nChannels =#Mono;
  WaveFormatEx\nSamplesPerSec = #SampleRate;
  WaveFormatEx\wBitsPerSample = $0008;
  WaveFormatEx\nBlockAlign = (WaveFormatEx\nChannels * WaveFormatEx\wBitsPerSample) /8
  WaveFormatEx\nAvgBytesPerSec = WaveFormatEx\nSamplesPerSec * WaveFormatEx\nBlockAlign;
  WaveFormatEx\cbSize = 0;
 
  DataCount = (duration * #SampleRate)/1000; // sound data
  RiffCount = 4+4 +4+ SizeOf(WAVE)+4 +4+ DataCount
 
  start=AllocateMemory(RiffCount+100)
  MS=start
 
  PokeS(MS,#RiffId):MS+4   ;'RIFF'
  PokeL(MS,RiffCount):MS+4 ;file Data size
  PokeS(MS,#WaveId):MS+4   ;'WAVE'
  PokeS(MS,#FmtId):MS+4    ;'fmt '
  TempInt = SizeOf(WAVE);
  PokeL(MS,TempInt):MS+4   ;TWaveFormat data size
 
  PokeW(MS,WaveFormatEx\wFormatTag):MS+2; WaveFormatEx record
  PokeW(MS,WaveFormatEx\nChannels):MS+2
  PokeL(MS,WaveFormatEx\nSamplesPerSec):MS+4
  PokeL(MS,WaveFormatEx\nAvgBytesPerSec):MS+4
  PokeW(MS,WaveFormatEx\nBlockAlign):MS+2
  PokeW(MS,WaveFormatEx\wBitsPerSample):MS+2
  PokeW(MS,WaveFormatEx\cbSize):MS+2
 
  PokeS(MS,#DataId):MS+4   ;'data'
  PokeL(MS,DataCount):MS+4 ;sound data size
 
  ;{Calculate And write out the tone signal}  // now the Data values
 
  w = 2 * #PI * Frequency;  omega
  For i = 0 To DataCount - 1
    ;// wt = w *i /SampleRate
    ;SoundValue := 127 + trunc(127 * Sin(i * w / SampleRate));
    SoundValue = 127 + 127 * Sin(i * w / #SampleRate);
    PokeB(MS,SoundValue):MS+1;
  Next
  ;// you could save the wave tone To file with :
  ;// MS.Seek(0, soFromBeginning);
  ;// MS.SaveToFile('C:\MyFile.wav');
  ;// then reload And play them without having To
  ;// construct them each time.
  ;{now play the sound}
  ;sndPlaySound(MS.Memory, SND_MEMORY Or SND_SYNC);
  ;MS.Free;
 
  CatchSound(nr,start)
 
  ProcedureReturn start
EndProcedure
 
Procedure QuitSound(nr, mem)
  StopSound(nr)
  FreeSound(nr)
  FreeMemory(mem)
EndProcedure
 
 
 
;}
Global Fgsf.l
Global mem.l
 
 
InitSound()
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 403, 164, 402, 253, "Генератор ЗЧ", #PB_Window_SystemMenu|#PB_Window_TitleBar)
    If CreateGadgetList(WindowID(#Window_0))
      TrackBarGadget(#TrackBarGadget_1, 40, 115, 305, 20, 0, 10000, #PB_TrackBar_Ticks):SetGadgetState(#TrackBarGadget_1,5000 )
 
      ButtonGadget(#ButtonGadget_2, 35, 175, 75, 35, "Вкл")
      ButtonGadget(#ButtonGadget_3, 250, 175, 85, 35, "Выкл")
      TextGadget(#TextGadget_0, 60, 30, 265, 60, "10000", #PB_Text_Center|#PB_Text_Border)
      ; Gadget Fonts
      SetGadgetFont(#TextGadget_0, LoadFont(#Font_TextGadget_0, "Impact", 36, 256))
      ; Gadget Colors
      ;PureCOLOR_SetGadgetColor(#TextGadget_0, $808080, $FF80); можно и так...
      SetGadgetColor(#TextGadget_0, #PB_Gadget_FrontColor, $808080)
      SetGadgetColor(#TextGadget_0, #PB_Gadget_BackColor, $FF80)
 
    EndIf
  EndIf
EndProcedure
 
OpenWindow_Window_0()
 
;{- Event loop
Repeat
  Event = WaitWindowEvent()
  Select Event
    ; ///////////////////
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      If EventGadget = #TrackBarGadget_1
      Fgsf=2*|!REG3XP3!>GetGadgetState(#TrackBarGadget_1)
      SetGadgetText(#TextGadget_0,Str(Fgsf))
      mem = MakeSound(0,Fgsf,2000)
      PlaySound(0,1)
      ElseIf EventGadget = #ButtonGadget_2
      mem = MakeSound(0,Fgsf,2000)
      PlaySound(0,1)
      ElseIf EventGadget = #ButtonGadget_3
       QuitSound(0, mem)
      ElseIf EventGadget = #TextGadget_0
      EndIf
    ; //////////////////////
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        Break
      EndIf
  EndSelect
ForEver
;}



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: FM radio
СообщениеДобавлено: Вс сен 18, 2016 10:17 am 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 201
Благодарил (а): 8 раз.
Поблагодарили: 26 раз.
Пункты репутации: 0
SereZa писал(а):
(а галки юникода и тредсейф в настройках стоят?). точнее пищит :)
Кстати да, не обратил внимание. Первый пример заработал. Ну так я понял здесь намек на DirectSound, не?
Кажись он выше уровнем и пользует те же структуры что и wave :x


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 152 ]  На страницу Пред.  1 ... 7, 8, 9, 10, 11  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB