Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/27: Рейтинг темы: голосов - 27, средняя оценка - 4.63
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443

Как грамотно соединить структуру с массивом?

14.05.2020, 22:07. Показов 5875. Ответов 75
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем здравствуйте!

Дано:
1. структура UDT
2. массив

Требуется соединить их вместе в одном массиве (типа Byte) так, чтобы новый массив начинался с членов данной структуры и продолжался/завершался членами данного массива. Для примера выбраны очень простенькие/маленькие структура и массив, но на самом деле они могут быть очень большими. И ещё условие задачи такое - циклами пользоваться нельзя, а то эдак я и сам могу тренькать, как сказал бы классик

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Option Explicit
 
Private Type MyUDT
  A As Integer
  B As Long
End Type
 
 
Private Sub Command1_Click()
  Dim udt_MyUDT As MyUDT
  Dim arr_Byte_array(1 To 3)  As Byte
  Dim arr_Total_array()  As Byte
 
 udt_MyUDT.A = 1
 udt_MyUDT.B = 2
 
  arr_Byte_array(1) = 3
  arr_Byte_array(2) = 4
  arr_Byte_array(3) = 5
 
 arr_Total_array() = ' ??????????????????????????????????????????????????????????
 
End Sub
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.05.2020, 22:07
Ответы с готовыми решениями:

как грамотно соединить в локальную сеть 5 ПК и 3 пятиэтажных дома
День добрый, подскажите как грамотно соединить в локальную сеть 5 ПК и 3 пятиэтажных дома , меня интересует оборудование, где поставить...

Как грамотно электрически и безопасно соединить ПК и ТВ кабелем HDMI-HDMI?
Здравствуйте! Компьютер питается из незаземлённой двухпроводной линии (розетки), видеокарта имеет выход HDMI. TV SMART питается из...

Стек соединить с массивом
Доброе время суток. Добрался я да коллекций. И ту мне попалась задачка из книжки "JAVA Методы программирование": создать в стеке...

75
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
22.05.2020, 15:07
Студворк — интернет-сервис помощи студентам
Power_Basic, почитайте документацию на acmFormatEnum и все станет понятно.
0
22.05.2020, 17:07  [ТС]

Не по теме:

Цитата Сообщение от locm Посмотреть сообщение
Цитата Сообщение от Power_Basic
В результате, мне эта функция вернула точно то, что я загружал в структуру MPEGLAYER3WAVEFORMAT
Результат выполнения какой?
Ну я же уже в своём предыдущем посте распечатал результаты:
UDT_MPEGLAYER3WAVEFORMAT.WFX.W FORMATTAG = 1 - (Hex: 00000001)
UDT_MPEGLAYER3WAVEFORMAT.WFX.N CHANNELS = 1 - (Hex: 00000001)
UDT_MPEGLAYER3WAVEFORMAT.WFX.N SAMPLESPERSEC = 22050 - (Hex: 00005622)
UDT_MPEGLAYER3WAVEFORMAT.WFX.W BITSPERSAMPLE = 8 - (Hex: 00000008)
UDT_MPEGLAYER3WAVEFORMAT.WFX.N BLOCKALIGN = 1 - (Hex: 00000001)
UDT_MPEGLAYER3WAVEFORMAT.WFX.N AVGBYTESPERSEC = 22050 - (Hex: 00005622)
UDT_MPEGLAYER3WAVEFORMAT.WFX.C BSIZE = 12 - (Hex: 0000000C)
UDT_MPEGLAYER3WAVEFORMAT.WID = 1 - (Hex: 00000001)
UDT_MPEGLAYER3WAVEFORMAT.FDWFL AGS = 2 - (Hex: 00000002)
UDT_MPEGLAYER3WAVEFORMAT.NBLOC KSIZE = 209 - (Hex: 000000D1)
UDT_MPEGLAYER3WAVEFORMAT.NFRAM ESPERBLOCK = 1 - (Hex: 00000001)
UDT_MPEGLAYER3WAVEFORMAT.NCODE CDELAY = 0 - (Hex: 00000000)
Функцию вызывал вот так:
PureBasic
1
2
3
4
5
6
7
8
9
10
11
'DECLARE FUNCTION acmFormatSuggest IMPORT "MSACM32.DLL" ALIAS "acmFormatSuggest" ( _
'   BYVAL had AS DWORD _                                 ' __in  HACMDRIVER had
' , BYREF pwfxSrc AS WAVEFORMATEX _                      ' __in  LPWAVEFORMATEX pwfxSrc
' , BYREF pwfxDst AS WAVEFORMATEX _                      ' __out LPWAVEFORMATEX pwfxDst
' , BYVAL cbwfxDst AS DWORD _                            ' __in  DWORD cbwfxDst
' , BYVAL fdwSuggest AS DWORD _                          ' __in  DWORD fdwSuggest
' ) AS DWORD                                             ' MMRESULT
 
  local dwrd_MMRESULT as DWORD
  dwrd_MMRESULT = acmFormatSuggest (%null, byval varptr(udt_WAVEFORMATEX), _
            byval varptr(udt_MPEGLAYER3WAVEFORMAT),  len (udt_MPEGLAYER3WAVEFORMAT), %ACM_FORMATSUGGESTF_NCHANNELS)
Предварительно заполнил структуру MPEGLAYER3WAVEFORMAT подходящими (на мой взгляд) значениями. Ну и она мне вернула те же самые значения в той же самой структуре. Но это очень хорошо. Получается, что я правильные значения ввёл "вручную".
А если вы под "результатом" имели в виду значение dwrd_MMRESULT, которое вернула эта функция, то оно, как и полагается, равно нулю ("успешное завершение").

Цитата Сообщение от locm Посмотреть сообщение
Код на PB. Может поймете.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
wfxSrc.WAVEFORMATEX
 MP3wfxDst.MPEGLAYER3WAVEFORMAT
SampleRate = 44100 ; Частота семплирования.
 BitRate = 128000 ; Битрейт MP3.
With wfxSrc
 \wFormatTag = #WAVE_FORMAT_PCM
 \nSamplesPerSec = SampleRate
 \nChannels = 2 ; Стерео.
 \wBitsPerSample = 16 ; 16-ти битный звук.
 \nBlockAlign = (\wBitsPerSample * \nChannels) / 8
 \nAvgBytesPerSec = \nSamplesPerSec * \nBlockAlign
 \cbSize = 0
 EndWith
With MP3wfxDst
 \wID = #MPEGLAYER3_ID_MPEG
 \wfx\wFormatTag = #WAVE_FORMAT_MPEGLAYER3
 \wfx\nChannels = 2 ; Стерео.
 \wfx\nSamplesPerSec = SampleRate
 \wfx\wBitsPerSample = 0
 \wfx\nAvgBytesPerSec = BitRate / 8
 \wfx\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES
 \wfx\nBlockAlign = 1
 EndWith
Не, ну здесь-то понять несложно. У меня, практически, то же самое, но только я умышленно выбрал характеристики звука поскромнее, поскольку для озвучивания текстов качество, думаю, будет вполне приемлемое:

PureBasic
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
   '' // Size = 18 bytes
   'TYPE WAVEFORMATEX BYTE
   '   wFormatTag      AS WORD    ' WORD    wFormatTag;        /* format type */
   '   nChannels       AS WORD    ' WORD    nChannels;         /* number of channels (i.e. mono, stereo...) */
   '   nSamplesPerSec  AS DWORD   ' DWORD   nSamplesPerSec;    /* sample rate */
   '   nAvgBytesPerSec AS DWORD   ' DWORD   nAvgBytesPerSec;   /* for buffer estimation */
   '   nBlockAlign     AS WORD    ' WORD    nBlockAlign;       /* block size of data */
   '   wBitsPerSample  AS WORD    ' WORD    wBitsPerSample;    /* Number of bits per sample of mono data */
   '   cbSize          AS WORD    ' WORD    cbSize;            /* The count in bytes of the size of extra information
   '                                                              (after cbSize) */
   'END TYPE
 
    local udt_WAVEFORMATEX as WAVEFORMATEX
 
    udt_WAVEFORMATEX.wFormatTag = %WAVE_FORMAT_PCM
    udt_WAVEFORMATEX.nChannels = 1
    udt_WAVEFORMATEX.nSamplesPerSec = 22050    'частота дискретизации
    udt_WAVEFORMATEX.wBitsPerSample = 8
    udt_WAVEFORMATEX.nBlockAlign = (udt_WAVEFORMATEX.wBitsPerSample / 8) * udt_WAVEFORMATEX.nChannels
    udt_WAVEFORMATEX.nAvgBytesPerSec = udt_WAVEFORMATEX.nBlockAlign * udt_WAVEFORMATEX.nSamplesPerSec
   'udt_WAVEFORMATEX.cbSize = 'Для форматов WAVE_FORMAT_PCM (и только для форматов WAVE_FORMAT_PCM)
                              'этот элемент игнорируется.
 
   '' // Size = 30 bytes
   'TYPE MPEGLAYER3WAVEFORMAT BYTE
   '   wfx             AS WAVEFORMATEX   ' WAVEFORMATEX  wfx
   '   wID             AS WORD           ' WORD          wID
   '   fdwFlags        AS DWORD          ' DWORD         fdwFlags
   '   nBlockSize      AS WORD           ' WORD          nBlockSize
   '   nFramesPerBlock AS WORD           ' WORD          nFramesPerBlock
   '   nCodecDelay     AS WORD           ' WORD          nCodecDelay
   'END TYPE
 
   local udt_MPEGLAYER3WAVEFORMAT as MPEGLAYER3WAVEFORMAT
 
    udt_MPEGLAYER3WAVEFORMAT.wfx.wFormatTag = %WAVE_FORMAT_MPEGLAYER3
    udt_MPEGLAYER3WAVEFORMAT.wfx.nChannels = 1
    udt_MPEGLAYER3WAVEFORMAT.wfx.nSamplesPerSec = 22050   'частота дискретизации
    udt_MPEGLAYER3WAVEFORMAT.wfx.wBitsPerSample = 8
    udt_MPEGLAYER3WAVEFORMAT.wfx.nBlockAlign = (udt_MPEGLAYER3WAVEFORMAT.wfx.wBitsPerSample / 8) * _
                                                                            udt_MPEGLAYER3WAVEFORMAT.wfx.nChannels
    udt_MPEGLAYER3WAVEFORMAT.wfx.nAvgBytesPerSec = udt_MPEGLAYER3WAVEFORMAT.wfx.nBlockAlign * _
                                                                            udt_MPEGLAYER3WAVEFORMAT.wfx.nSamplesPerSec
    udt_MPEGLAYER3WAVEFORMAT.wfx.cbSize = %MPEGLAYER3_WFX_EXTRA_BYTES
    udt_MPEGLAYER3WAVEFORMAT.wID = %MPEGLAYER3_ID_MPEG
    udt_MPEGLAYER3WAVEFORMAT.fdwFlags = %MPEGLAYER3_FLAG_PADDING_OFF
 
'Формат MP3 сжатия аудио с потерями данных. Качество звука улучшается с увеличением битрейта:
'    битрейт 32 кбит/сек — как правило, приемлемо только для речи
'    битрейт 96 кбит/сек — как правило, используется для передачи речи или потокового звука низкого качества
'    битрейт 128 или 160 кбит/сек — начальный уровень кодирования музыки
'    битрейт 192 кбит/сек — приемлемое качество кодирования музыки
'    битрейт 256 кбит/сек — высокое качество кодирования музыки
'    битрейт 320 кбит/сек — наивысшее качество кодирования, поддерживаемое стандартом MP3
 
    udt_MPEGLAYER3WAVEFORMAT.nBlockSize = 144 * _                      '144 x (bitrate / sample rate) + padding.
    (32000 / udt_MPEGLAYER3WAVEFORMAT.wfx.nSamplesPerSec)
    udt_MPEGLAYER3WAVEFORMAT.nFramesPerBlock   = 1
    udt_MPEGLAYER3WAVEFORMAT.nCodecDelay = 0
 
'DECLARE FUNCTION acmFormatSuggest IMPORT "MSACM32.DLL" ALIAS "acmFormatSuggest" ( _
'   BYVAL had AS DWORD _                                 ' __in  HACMDRIVER had
' , BYREF pwfxSrc AS WAVEFORMATEX _                      ' __in  LPWAVEFORMATEX pwfxSrc
' , BYREF pwfxDst AS WAVEFORMATEX _                      ' __out LPWAVEFORMATEX pwfxDst
' , BYVAL cbwfxDst AS DWORD _                            ' __in  DWORD cbwfxDst
' , BYVAL fdwSuggest AS DWORD _                          ' __in  DWORD fdwSuggest
' ) AS DWORD                                             ' MMRESULT
 
  local dwrd_MMRESULT as DWORD
  dwrd_MMRESULT = acmFormatSuggest (%null, byval varptr(udt_WAVEFORMATEX), _
            byval varptr(udt_MPEGLAYER3WAVEFORMAT),  len (udt_MPEGLAYER3WAVEFORMAT), %ACM_FORMATSUGGESTF_NCHANNELS)
Цитата Сообщение от The trick Посмотреть сообщение
Power_Basic, почитайте документацию на acmFormatEnum и все станет понятно.
Посмотрел... Но там дебри ещё те. Эдак я совсем с пути собьюсь :)
Структуры-то я худо-бедно уже заполнил и даже "необязательную" функцию acmFormatSuggest уже вполне успешно вызвал. Следующий пункт в моей дорожной карте это функция acmStreamOpen:

Цитата Сообщение от locm Посмотреть сообщение
Последовательность такова. Заполняем структуры WAVEFORMATEX и MPEGLAYER3WAVEFORMAT, передаем их функции acmFormatSuggest (не обязательно) а после функции acmStreamOpen. Следим за тем чтобы функции возвращали MMSYSERR_NOERROR.
После вызываем acmStreamSize чтобы получить размеры буферов. Создаем буферы и помещаем указатели на них в структуру ACMSTREAMHEADER и вызываем acmStreamPrepareHeader.
А дальше вызываем acmStreamConvert передавая WAV данные и получаем MP3 данные.

0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
22.05.2020, 21:34
Цитата Сообщение от Power_Basic Посмотреть сообщение
Посмотрел... Но там дебри ещё те. Эдак я совсем с пути собьюсь
Структуры-то я худо-бедно уже заполнил и даже "необязательную" функцию acmFormatSuggest уже вполне успешно вызвал. Следующий пункт в моей дорожной карте это функция acmStreamOpen:
Нет. Ты когда-нибудь работал с программами которые позволяют сохранить свои данные в каком-нибудь звуковом формате? В подавляющем большинстве случаев тебе будет показан список форматов в которые ты можешь сохранить данные. К примеру:
GoldWave:

VirtualDub:

Так вот acmFormatEnum позволяет определить для определенного входного формата список форматов в который можно сконвертировать этот формат. В итоге получишь уже заполненные структуры MPEGLAYER3WAVEFORMAT и их текстовое описание.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
22.05.2020, 23:48  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Нет. Ты когда-нибудь работал с программами которые позволяют сохранить свои данные в каком-нибудь звуковом формате? В подавляющем большинстве случаев тебе будет показан список форматов в которые ты можешь сохранить данные. К примеру:
GoldWave:
VirtualDub:
Ну да, конечно же, работал. С Sound Forge, например.

Цитата Сообщение от The trick Посмотреть сообщение
Так вот acmFormatEnum позволяет определить для определенного входного формата список форматов в который можно сконвертировать этот формат. В итоге получишь уже заполненные структуры MPEGLAYER3WAVEFORMAT и их текстовое описание.
Ну тогда да, тогда это очень удобно. Спасибо за информацию!
0
23.05.2020, 23:30  [ТС]

Не по теме:

Цитата Сообщение от locm
Последовательность такова. Заполняем структуры WAVEFORMATEX и MPEGLAYER3WAVEFORMAT, передаем их функции acmFormatSuggest (не обязательно) а после функции acmStreamOpen. Следим за тем чтобы функции возвращали MMSYSERR_NOERROR.
После вызываем acmStreamSize чтобы получить размеры буферов. Создаем буферы и помещаем указатели на них в структуру ACMSTREAMHEADER и вызываем acmStreamPrepareHeader.
А дальше вызываем acmStreamConvert передавая WAV данные и получаем MP3 данные.
На самом деле, замечательная дорожная карта, иду по ней с удовольствием, как по ковровой дорожке, честное слово.
Прошёл уже весь путь до закрытия ACM потока. В результате пока General Protection Fault, но это нормально, потому что у меня по ходу дела возникали некоторые вопросы, но я их оставлял без ответа и действовал по своим догадкам.
Собственно, главный вопрос, который сейчас меня очень сильно интересует, таков:

Там по ходу дела просят дать ссылки на буферы источника и назначения. Ну с назначением всё более или менее понятно, - это просто какое-то новое место в памяти. А вот с буфером источника не понятно: то ли тоже надо указывать какое-то новое место в памяти, то ли надо указывать на массиив байтов нашего "сырого" аудиопотока? Я указал на массиив байтов нашего "сырого" аудиопотока, но что-то мне подсказывает, что всё-таки буфер должен быть в каком-то отдельном месте, а не на "промежуточном продукте".
Но тогда получается, что функцию acmStreamSize следует вызывать дважды, сначала с флагом ACM_STREAMSIZEF_SOURCE, а потом с флагом ACM_STREAMSIZEF_DESTINATION, или всё-таки только один раз?

Собственно, сейчас это мой главный камень преткновения.

0
24.05.2020, 13:44

Не по теме:

Цитата Сообщение от Power_Basic Посмотреть сообщение
А вот с буфером источника не понятно: то ли тоже надо указывать какое-то новое место в памяти, то ли надо указывать на массиив байтов нашего "сырого" аудиопотока?
"Новое место в памяти". В него копируются данные "сырого" аудиопотока. В этом коде \ash\pbSrc это исходный буфер.
Цитата Сообщение от Power_Basic Посмотреть сообщение
Но тогда получается, что функцию acmStreamSize следует вызывать дважды, сначала с флагом ACM_STREAMSIZEF_SOURCE, а потом с флагом ACM_STREAMSIZEF_DESTINATION, или всё-таки только один раз?
Один раз с ACM_STREAMSIZEF_SOURCE. В этом случае будет рассчитан размер буфера pbDst по известному размеру pbSrc.

0
25.05.2020, 03:52  [ТС]

Не по теме:

locm, ну вот сейчас удалось сконвертировать. Результат всех функций вернул ноль (успешное завершение).
Но почему-то ничего не сжалось. MP3 файл даже слегка больше по размеру чем WAV файл, который сбрасывается на диск (для контроля правильности предыдущих действий) перед конвертацией. Да и сам MP3 файл не воспроизводится по щелчкам мыши, а требует для прослушивания стороннюю программу, умеющую воспроизводить сырые аудиопотоки.
Я приложил к посту простенькую программу на PowerBasic'е, которую написал специально для изучения конвертации WAV в MP3, а также и сами полученные файлы WAV и MP3.

Вложения
Тип файла: zip 01.ZIP (21.2 Кб, 0 просмотров)
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
25.05.2020, 03:54  [ТС]
Как я понял, вложения отказываются прикрепляться к оффтопным постам, печаль
Вложения
Тип файла: zip 01.ZIP (21.2 Кб, 3 просмотров)
0
26.05.2020, 00:45  [ТС]

Не по теме:

Цитата Сообщение от locm
Последовательность такова. Заполняем структуры WAVEFORMATEX и MPEGLAYER3WAVEFORMAT, передаем их функции acmFormatSuggest (не обязательно) а после функции acmStreamOpen.
Как выяснилось, эта функция в данном случае скорее даже вредна чем полезна.

Поскольку ничего у меня с кавалерийского наскока не получилось, приходится волей-неволей засесть за изучение теории :)
И вот, что я только что вычитал:

Выбор наиболее подходящего формата
В том случае, когда имеется сжатый формат, который должен быть восстановлен в формат PCM, приложение может воспользоваться функцией acmFormatSuggest. Эта функция подберет наиболее подходящий формат типа PCM, в который следует восстановить исходный сжатый формат.
Ну то есть это совершенно обратная задача. Восстановление вместо сжатия. Наверно, потому и получается у меня на выходе почти то же самое, что и на входе :)

Прав, The trick, как выясняется. Без этого шага всё-таки не обойтись:
Цитата Сообщение от The trick
Так вот acmFormatEnum позволяет определить для определенного входного формата список форматов в который можно сконвертировать этот формат. В итоге получишь уже заполненные структуры MPEGLAYER3WAVEFORMAT и их текстовое описание.
Честно говоря, я почему-то надеялся, что мне Windows самостоятельно подберёт какой-нибудь кодек, подходящий под параметры, которыми я заполнил структуры WAVEFORMATEX и MPEGLAYER3WAVEFORMAT.

Мою надежду подпитывало ещё и то, что в функции acmStreamOpen параметр had имеет вот такое описание:

Хэндл к драйверу ACM. Если указан этот хэндл, он определяет конкретный драйвер, который будет использоваться для потока преобразования. Если этот параметр равен NULL, все подходящие установленные драйверы ACM запрашиваются, пока не будет найдено соответствие.
Ну вот я и установил этот параметр в ноль и понадеялся на автоматику :)
Но она, увы, подвела :)
Придётся начинать всё с самого начала и уже "вручную" :)

0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
26.05.2020, 15:00
Цитата Сообщение от Power_Basic Посмотреть сообщение
Прав, The trick, как выясняется.
Почему не сделать так как я изначально описал?
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
26.05.2020, 23:03  [ТС]

Не по теме:

Цитата Сообщение от The trick Посмотреть сообщение
Цитата Сообщение от Power_Basic
Прав, The trick, как выясняется.
Почему не сделать так как я изначально описал?
А это уже из области психологии :)
На одной чаше весов описание полного алгоритма действий, а на другой только одного (пусть даже и очень важного) этапа.
Ну и что выбрать? Разумеется, выбираем полный алгоритм, проходим быстренько весь путь от начала до конца, а потом, уже ознакомившись на практике с самыми важными вехами, и в том случае, если получен неудовлетворительный результат, возвращаемся назад и ищем ошибку.

Хотя, с другой стороны, вы, конечно, даже ссылку дали на код, который делает всю работу по конвертации от начала до конца. И более того, этот код написан на близком и родном мне Визуальном Бейсике. Но всё-таки чужие программы я понимаю с трудом, даже когда они написаны на понятных мне языках, это раз. Ну а во-вторых, не пройдя весь путь от начала до конца, я вообще не понимал, что мы там делаем :)
Ну вот теперь вернусь и буду разбираться уже с учётом накопленного опыта :)

Проблема же ещё и в том, что я по жизни совсем не меломан, и для меня все эти битрейты, семплы и всё такое это вообще нечто совершенно мне не нужное и чужеродное :)
Ну просто сейчас вот возникла потребность озвучить текст, ну вот и приходится нырять во всю эту "музыку" :)
И это как раз тот случай, когда хочется сделать поскорее, "на троечку", не особо вникая в интимные подробности :)
Ну не получилось, придётся вникать :)
Хотя в этом, конечно же, тоже есть своя неоспоримая польза.



Добавлено через 5 часов 30 минут

Не по теме:

Цитата Сообщение от locm Посмотреть сообщение
Код на PB. Может поймете.
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
wfxSrc.WAVEFORMATEX
 MP3wfxDst.MPEGLAYER3WAVEFORMAT
SampleRate = 44100 ; Частота семплирования.
 BitRate = 128000 ; Битрейт MP3.
With wfxSrc
 \wFormatTag = #WAVE_FORMAT_PCM
 \nSamplesPerSec = SampleRate
 \nChannels = 2 ; Стерео.
 \wBitsPerSample = 16 ; 16-ти битный звук.
 \nBlockAlign = (\wBitsPerSample * \nChannels) / 8
 \nAvgBytesPerSec = \nSamplesPerSec * \nBlockAlign
 \cbSize = 0
 EndWith
With MP3wfxDst
 \wID = #MPEGLAYER3_ID_MPEG
 \wfx\wFormatTag = #WAVE_FORMAT_MPEGLAYER3
 \wfx\nChannels = 2 ; Стерео.
 \wfx\nSamplesPerSec = SampleRate
 \wfx\wBitsPerSample = 0
 \wfx\nAvgBytesPerSec = BitRate / 8
 \wfx\cbSize = #MPEGLAYER3_WFX_EXTRA_BYTES
 \wfx\nBlockAlign = 1
 EndWith
Ура, заработало!!!
Ну просто тупо скопировал отсюда все значения в обе структуры и пазл неожиданно сложился :)
Почему так, совершенно не понимаю.
Каким-то непонятным образом у нас здесь BitsPerSample в структуре MPEGLAYER3WAVEFORMAT раен нулю, хотя в структуре WAVEFORMATEX он же равен 16-ти.
Да и кроме того некоторые вроде бы очень важные члены структуры MPEGLAYER3WAVEFORMAT вообще оставлены безо всякого внимания. Я сейчас говорю про fdwFlags, nFramesPerBlock, nBlockSize и nCodecDelay.
А ведь я их так старательно заполнял :)
А теперь вот закомментировал и всё заработало, чудеса :)

Но всё-таки для моих чисто речевых нужд такие характеристики звука явно "жирноваты". У меня даже в самом названии речевого движка фигурирует цифра 22kHz, а здесь 44kHz.

PureBasic
1
2
$Russian_voice_name = "Vocalizer Expressive Yuri Harpo 22kHz"
$English_voice_name = "ScanSoft Daniel_Full_22kHz"
Стерео мне тоже совершенно ни к чему, да и 8 бит вместо 16 вполне бы хватило, я уверен.
Разумеется, попробовал подставить "свои" параметры, оставив всё остальное без изменений. Не работает :(

Ну да и ладно. В конце концов, MP3 файл сжат очень хорошо (относительно исходого WAV), а именно в 11,5 раз.
Ну и короче говоря, меня вполне устраивает достигнутый результат.

locm и The trick, огромное спасибо за помощь!!!

0
27.05.2020, 00:46

Не по теме:

Цитата Сообщение от Power_Basic Посмотреть сообщение
Разумеется, попробовал подставить "свои" параметры, оставив всё остальное без изменений. Не работает
Функция acmFormatSuggest вызывается?
Она проверяет корректность заполнения структур и изменяет данные при необходимости.

0
27.05.2020, 02:48  [ТС]

Не по теме:

Цитата Сообщение от locm Посмотреть сообщение
Функция acmFormatSuggest вызывается?
Она проверяет корректность заполнения структур и изменяет данные при необходимости.
Ну да, проверяет и изменяет, но только так изменяет, что потом вместо файла MP3, размер которого меньше файла WAV в 11,5 раз, создаётся файл MP3, который даже слегка больше чем WAV-файл, но самое неприятное, что он совершенно не реагирует на попытки запустить его в каком-нибудь проигрывателе. Это просто слегка видоизменённый сырой аудиопоток. Например, его можно прослушать в программе Audacity, которая умеет импортировать и воспроизводить сырые аудиопотоки.

Я немного поэкспериментировал с вашими данными. Как я уже говорил выше, без использования функции acmFormatSuggest всё работает замечательно (с вашими данными для структуры MPEGLAYER3WAVEFORMAT).
А вот как изменяет эта функция эти данные, после чего сжатие аудиопотока уже не происходит(и причём сама функция сигнализирует нулём об успешном завершении операции):
WFORMATTAG = 85 'было
WFORMATTAG = 1 'стало

WBITSPERSAMPLE = 0 'было
WBITSPERSAMPLE = 16 'стало

NBLOCKALIGN = 1 'было
NBLOCKALIGN = 4 'стало

NAVGBYTESPERSEC = 16000 'было
NAVGBYTESPERSEC = 176400 'стало

======================================== ==============
NCHANNELS = 2 'было
NCHANNELS = 2 'не изменилось

NSAMPLESPERSEC = 44100 'было
NSAMPLESPERSEC = 44100 'не изменилось

CBSIZE = 12 'было
CBSIZE = 12 'не изменилось

WID = 1 'было
WID = 1 'не изменилось

FDWFLAGS = 0 'было
FDWFLAGS = 0 'не изменилось

NBLOCKSIZE = 0 'было
NBLOCKSIZE = 0 'не изменилось

NFRAMESPERBLOCK = 0 'было
NFRAMESPERBLOCK = 0 'не изменилось

NCODECDELAY = 0 'было
NCODECDELAY = 0 'не изменилось
А что касается данных в структуре WAVEFORMATEX, то эта функция их совсем никак не изменяет.

0
27.05.2020, 21:41  [ТС]

Не по теме:

The trick и locm, будете смеяться, но я всё сделал методом подбора :)
Ну короче, "играл" вот этими (назовём их "динамическими") параметрами структуры MPEGLAYER3WAVEFORMAT в нескольких вложенных друг в друга циклах FOR ... NEXT:

wBitsPerSample
nAvgBytesPerSec
nBlockAlign
И при этом для каждой новой комбинации пробовал вызвать функцию acmStreamOpen. Когда она сигнализировала нулём о успешном открытии потока, параметры записывались, поток закрывался и следовала новая итерация.

Чтобы "нащупать" разнообразные допустимые комбинации, сначала отталкивался от тех параметров, которые предложил locm (назовём их "статическими"). Напомню, что там было стерео 44кГЦ, 16 бит.

Потом стал постепенно вводить свои статические параметры, продолжая играть динамическими. Сначала изменил моно на стерео, потом 44кГЦ на 22кГЦ. И каждый раз находилось несколько возможных значений динамических параметров, при которых поток нормально запускался.
Критичным оказался только статический параметр WAVEFORMATEX.wBitsPerSample = 16. При любых попытках изменить его на восьмёрку, никакие динамические комбинации уже не срабатывали.
Ну и решил на этом остановиться :)

Выводы:
(напомню, что каждый раз озвучивалась одна и та же фраза "Всем привет!")

1. В первом варианте (стерео 44кГЦ, 16 бит) размер WAV-файла составил 326280 байт, а MP3-файла 28421 байт (сжатие приблизительно в 11,5 раз).
Во втором варианте (моно 22кГЦ, 16 бит) размер WAV-файла составил 81594 байт, а MP3-файла 5172 байт (сжатие приблизительно в 17,5 раз).

2. А вот это самый удивительный (ну по крайней мере, для меня) вывод:
Из всех полей структуры MPEGLAYER3WAVEFORMAT заполнить достаточно только вот эти:

PureBasic
1
2
3
4
5
6
7
  wFormatTag                        ' (= %WAVE_FORMAT_MPEGLAYER3)
  wID                                            ' ( = %MPEGLAYER3_ID_MPEG)
  cbSize                                         ' (= %MPEGLAYER3_WFX_EXTRA_BYTES)
 
  nChannels
  nSamplesPerSec
  nAvgBytesPerSec
А все остальные (а их там, на самом деле, довольно много) поля можно вообще проигнорировать. Они там сами собой инициализируются нулями и этого, как выясняется, вполне достаточно для открытия потока и дальнейшей работы :)

0
27.05.2020, 22:21

Не по теме:

На размер файла сильно влияет битрейт. Попробуйте при 22КГц и 16 бит найти минимальное значение битрейта (поле nAvgBytesPerSec в MPEGLAYER3WAVEFORMAT). Насколько помню минимум 16000/8 т. е. 2000.

0
27.05.2020, 23:44  [ТС]

Не по теме:

Цитата Сообщение от locm Посмотреть сообщение
На размер файла сильно влияет битрейт. Попробуйте при 22КГц и 16 бит найти минимальное значение битрейта (поле nAvgBytesPerSec в MPEGLAYER3WAVEFORMAT). Насколько помню минимум 16000/8 т. е. 2000.
У меня минимум 3000.
PureBasic
1
MPEGLAYER3WAVEFORMAT.wfx.nAvgBytesPerSec = 3000
А вообще допустимые значения, при которых поток открывается, это 3000, 4000, 5000 и 6000.
У меня как раз и выбрано минимальное значение.

Но, конечно, такой "партизанский" подход, как я понимаю, годится только для тех, кто пишет программы исключительно для своего домашнего использования, ну как я например.
А иначе у конечного пользователя может не оказаться нужного драйвера/кодека и программа уже не справится с конвертацией.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.05.2020, 23:44
Помогаю со студенческими работами здесь

Создать структуру для работы с массивом
пробую написать программу с использованием структуры.. Создать структуру для работы с массивом. Данные структуры: массив N(10)....

Как создать структуру-список, поля которой — ссылка на такую же структуру
Суть вопроса в том, как создать структуру-список, поля которой - ссылка на сл. элемент(такую же структуру) и ссылка на объект, относящийся...

Как создать структуру, где будут поля с указателями на эту же структуру?
#include <stdio.h> #include <stdlib.h> typedef struct DoubleQueue { queue* ar; queue* al; int data; }...

Как правильно написать функцию, которая редактирует структуру по полю Name и возвращает новую, исправленную структуру?..
Нужно отредактировать структуру по выбору пользователя. Проблема заключается в создании функции. Подскажите, а лучше покажите, как...

как грамотно форматировать?
подскажите как грамотно форматировать данный код? <div class="penci_post_content"><h3 class="penci__post-title...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
76
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru