powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Не понятно как шагать...
18 сообщений из 18, страница 1 из 1
Не понятно как шагать...
    #33693551
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такое описание в MSDN, что если вы конвертите WAV с одного формата в другой, например PCM в ALAW, то с помощью функций acm* придется конвертить в несколько шагов. Сначала PCM в требуемый формат, потом то что получилось в ALAW. Хорошо пробую. Первый шаг проходит на ура (кроме 4-х канальных и 4-х битных форматов). Ладно, но дальше дело не идет!!!

В чем может быть дело? Подбираю формат следующим образом:
Код: plaintext
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.
	wfxSrc.nChannels=twSrc->channels;
	wfxSrc.nSamplesPerSec=twSrc->freq;
	wfxSrc.nAvgBytesPerSec=twSrc->bytes;
	wfxSrc.nBlockAlign=twSrc->align;
	wfxSrc.wBitsPerSample=twSrc->bits;
	wfxSrc.cbSize= 0 ;

	if (ret=wav2win(type, &(wfxDst.wFormatTag))) return - 15 +ret;
	wfxDst.nChannels=channels;
	wfxDst.nSamplesPerSec=freq;
	wfxDst.wBitsPerSample=bits;
	wfxDst.cbSize= 0 ;

		if (ret=acmFormatSuggest(NULL, &wfxSrc, &wfxDst, sizeof (wfxDst)+CONVERT_EXT_BUFFER, 
									ACM_FORMATSUGGESTF_WFORMATTAG
									| ACM_FORMATSUGGESTF_NSAMPLESPERSEC
									| ACM_FORMATSUGGESTF_NCHANNELS 
									| ACM_FORMATSUGGESTF_WBITSPERSAMPLE
		)) {
			switch (ret) {
				case MMSYSERR_INVALFLAG: return - 25 ;
				case MMSYSERR_INVALHANDLE: return - 26 ;
				case MMSYSERR_INVALPARAM: return - 27 ;
				case ACMERR_NOTPOSSIBLE: return - 28 ;
				default: return - 29 ;
			}
		}

Все вываливается на -28-й ошибке.

Единственное, что получилось сделать, это сконвертнуть на ADPCM 1-channels 11250 4bits.

Подскажите, пожалуйста, в чем может быть дело?

И вопрос в догонку. Может, кто-нибудь, может подсказать, какие форматы, изначально не корректны. Например, складывается впечатление, что PCM не бывает 4-х канальным и 4-х битным.

Заранее благодарен.
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33693593
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В начале преведенного сырца, есстественно, пропущена строчка (забыл скопировать):

Код: plaintext
	if (ret=wav2win(twSrc->type, &(wfxSrc.wFormatTag))) return - 5 +ret;
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33693940
Maksim UM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть некоторые мысли
Есть намеки (например на acmFormatTagDetails для проверки)
Некоторые стандартные кодеки могут только декодировать...
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33694246
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksim UM Есть некоторые мысли
Есть намеки (например на acmFormatTagDetails для проверки)
Некоторые стандартные кодеки могут только декодировать...

Начал копать в подборе требуемых драйверов. На это натолкнула мысль, что acmFormatChoose дает на выбор только несколько драйверов. Возможно acmFormatSuggest тоже пытается выбрать по какому-то маленькому списку.

1. Первая ссылка утвердила меня в том, что надо выдавать в Suggest нужный драйвер, а не выбирать автоматический поиск драйвера - NULL
2. Вторую ссылку я уже обчитался.
3. Учту.

Спасибо, за советы.

Может у кого-нибудь есть ссылки или примеры по выбору подходящего драйвера? Я пробую через acmDriverDetails. Сейчас пытаюсь решить следующие вопросы:
1. Как определить форматы, поддерживаемые драйвером?
2. Как определить в какие форматы он умеет кодировать, а в какие декодировать?
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33694402
Maksim UM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в мсдне (вторая ссылка) описана куча enum'ов,
например acmFormatEnum.
С помощью них можно определить что поддерживается.
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33694541
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksim UMв мсдне (вторая ссылка) описана куча enum'ов,
например acmFormatEnum.
С помощью них можно определить что поддерживается.

Похоже я был не прав. Я начал копать с acmDriverEnum, а надо было с acmFormatEnum. :( Насколько я понял, только так можно получить нужный драйвер, т.к. details драйвера такой информации не предоствляет. Да и второй способ рациональней
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33695365
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему вылетает access violetion?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
	Details.cbStruct=sizeof(ACMFORMATDETAILS);
	Details.pwfx=&Format;
	Details.cbwfx=sizeof(WAVEFORMATEX)+CONVERT_EXT_BUFFER;
	Details.dwFormatTag=type;
	Details.dwFormatIndex= 0 ;
	Details.fdwSupport= 0 ;
	Details.szFormat[ 0 ]= 0 ;

	Format.wFormatTag=type;
	Format.nChannels=channels;
	Format.nSamplesPerSec=freq;
	Format.wBitsPerSample=bits;
	Format.cbSize= 0 ;

	if (acmFormatEnum (
		NULL, 
		&Details,
		fmtCb,
		MY_FMT_ENUM_INSTANCE, 
		ACM_FORMATENUMF_CONVERT
	)) return - 2 ;
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33695398
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, кстати, ошибка вылетает после того, как один раз Callback обработался.
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33695586
Maksim UM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
дк... потому, что access того, violetion...
так не скажешь. нужно код видеть.
а проще в отладчике поглядеть
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33695643
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksim UMдк... потому, что access того, violetion...
так не скажешь. нужно код видеть.
а проще в отладчике поглядеть

В отладчике выхожу из коллбака, иду дальше по машиннному коду, долго долго иду и кирдык.
Если по машинному коду не идти, то большо на текст программы отладчик не возвращает.

1. Какие куски кода показать? (весь код уже содержит много функций, и состоит из библиотеки на VC++ и клиенте на Delphi)

2. Балуюсь с последним параметром acmFormatEnum() - флаги, по которым подбирать форматы, так результаты самые не понятные. То он мне только PCM предлогает, то 1 (!) только какой-то формат 85, то, вообще, программа вылетает без всякик access'ов.

Приведу некоторые части кода, которые мне кажутся интересными:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
	if (acmFormatEnum (
		NULL,
		&Details,
		fmtCb,
		MY_FMT_ENUM_INSTANCE, 
//		ACM_FORMATENUMF_WFORMATTAG | ACM_FORMATENUMF_NSAMPLESPERSEC | ACM_FORMATENUMF_NCHANNELS | ACM_FORMATENUMF_WBITSPERSAMPLE | ACM_FORMATENUMF_CONVERT
//		ACM_FORMATENUMF_SUGGEST
		ACM_FORMATENUMF_SUGGEST
	)) return - 2 ;


Да в принципе и все. Не знаю, что будет еще нужно показать. Справшивайте.
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33696825
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллбак объявлен как:

Код: plaintext
1.
BOOL CALLBACK fmtCb(HACMDRIVERID id, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport) {

Это правельно?
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33696873
Maksim UM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а не так случайно?
Код: plaintext
1.
BOOL ACMFORMATENUMCB fmtCb(HACMDRIVERID id, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)
Но проблема возможно в другом.
Надо поставить вывод в лог файл контрольные точки в колбэке
(после каждой строки кода).
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33697037
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksim UMа не так случайно?
Код: plaintext
1.
BOOL ACMFORMATENUMCB fmtCb(HACMDRIVERID id, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)
Но проблема возможно в другом.
Надо поставить вывод в лог файл контрольные точки в колбэке
(после каждой строки кода).

1. Дело в том, что так оно не компилится:
Код: plaintext
1.
2.
3.
c:\work\projects\ip telephone\acmconv\asmconv.c( 865 ) : error C2061: syntax error : identifier 'fmtTagCb'
c:\work\projects\ip telephone\acmconv\asmconv.c( 865 ) : error C2059: syntax error : ';'
c:\work\projects\ip telephone\acmconv\asmconv.c( 865 ) : error C2059: syntax error : 'type'

Врядли, дело в с.

2. А что это дает? Я смотрел в дебаггере. Каллбак дебагится на ура.
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33697065
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я никак не врублюсь, что надо указывать в Details, Format и последнем параметре acmFormatEnum (флаги ограничения области перебора), чтобы выдать запрос на перебор всех форматов, в которые можно сконвертить из данного.

Код: plaintext
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.
CMCONVDLL acmConvGetFmtCount(int *count, int type, int channels, long freq, int bits) {
	WAVEFORMATEX     Format;
	BYTE Ext[CONVERT_EXT_BUFFER];
	ACMFORMATDETAILS Details;
	int ret;
	
	if (count==NULL) return - 1 ;

	if (drvInfo!=NULL) {
		free(drvInfo);
		drvInfo=NULL;
	}
	drvInfo_n= 0 ;

	Details.cbStruct=sizeof(ACMFORMATDETAILS);
	Details.pwfx=&Format;
	Details.cbwfx=sizeof(WAVEFORMATEX)+CONVERT_EXT_BUFFER;
	if (ret=wav2winl(type, &(Details.dwFormatTag))) return- 2 +ret; 
	Details.dwFormatIndex= 0 ;
	Details.fdwSupport= 0 ;
	Details.szFormat[ 0 ]= 0 ;

//wav2win - переводит из типов, которые указываются в заголовках wav файлов в типы по mmreg.h
	if (ret=wav2wins(type, &(Format.wFormatTag))) return- 11 +ret; 
	Format.nChannels=channels;
	Format.nSamplesPerSec=freq;
	Format.wBitsPerSample=bits;
	Format.cbSize= 0 ;

	if (acmFormatEnum (
		NULL,
		&Details,
		fmtCb,
		MY_FMT_ENUM_INSTANCE, 
		ACM_FORMATENUMF_WFORMATTAG | ACM_FORMATENUMF_NSAMPLESPERSEC | ACM_FORMATENUMF_NCHANNELS | ACM_FORMATENUMF_WBITSPERSAMPLE | ACM_FORMATENUMF_CONVERT
	)) return - 21 ;

//В это время работает callback


	(*count)=drvInfo_n;
	if (drvInfo_n< 0 ) return  1 ;
	else return  0 ;
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
BOOL CALLBACK fmtCb(HACMDRIVERID id, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport) {
	if (dwInstance==MY_FMT_ENUM_INSTANCE) {
		if (drvInfo==NULL) {
			if (!(drvInfo=(acmConvInfo *)malloc(sizeof(acmConvInfo)))) {
				drvInfo_n=- 1 ;
				return FALSE;
			}
		} else {
			if (!(drvInfo=(acmConvInfo *)realloc(drvInfo, sizeof(acmConvInfo)*(drvInfo_n+ 1 )))) {
				drvInfo_n=- 1 *(drvInfo_n+ 1 );
				return FALSE;
			}
		}

		drvInfo[drvInfo_n].drvID = id;
		drvInfo[drvInfo_n].drvF = fdwSupport;
		strcpy(drvInfo[drvInfo_n].drvName, pafd->szFormat);
		memcpy(&(drvInfo[drvInfo_n].drvFmt), pafd->pwfx, sizeof(WAVEFORMATEX)+CONVERT_EXT_BUFFER);
		drvInfo_n++;
	}

	return TRUE;
}

Структуры:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#define MY_FMT_ENUM_INSTANCE  2 

struct TacmConvInfo {
	HACMDRIVERID drvID;
	DWORD drvF;
	char drvName[ACMFORMATDETAILS_FORMAT_CHARS];
	WAVEFORMATEX drvFmt; 
	BYTE Ext[CONVERT_EXT_BUFFER];
};

typedef struct TacmConvInfo acmConvInfo;

acmConvInfo *drvInfo=NULL;
int drvInfo_n= 0 ;
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33698130
Maksim UM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тяжело так сходу сказать, но во первых,
вот еще одна хорошая ссылка ,
а во-вторых, чему равно CONVERT_EXT_BUFFER?
дополнительный довесок может быть разный.
С помощью acmMetrics и acmFormatTagDetails можно уточнять размер.
можно попробовать увеличить CONVERT_EXT_BUFFER.
И все-таки, второй раз колбэк получает управление,
если да то в каком месте ошибка?
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33698206
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksim UMТяжело так сходу сказать, но во первых,
вот еще одна хорошая ссылка ,
а во-вторых, чему равно CONVERT_EXT_BUFFER?
дополнительный довесок может быть разный.
С помощью acmMetrics и acmFormatTagDetails можно уточнять размер.
можно попробовать увеличить CONVERT_EXT_BUFFER.
И все-таки, второй раз колбэк получает управление,
если да то в каком месте ошибка?

За ссылку спасибо. Но она уже дня 3 как стала моей библией. :)

На счет CONVERT_EXT_BUFFER и всего, что с ним связано (BYTE Ext[CONVERT_EXT_BUFFER]). Эта константа равна 1024. Я так понимаю, что чем больше тем, лучше. В msdn'е указаны разные размеры для разных кодеков, но обычно 30-50 байт. В одном примере видел, что выбирают 128 байт, так что я думаю, что 1024 - это будет хорошо.

С вылетанием разобрался. Дело было в этих довесках (CONVERT_EXT_BUFFER), я осознанно поступал не корректно, объявляя довески сразу после структур. Не хотелось акцинтировать на этом внимание. В итоге, оказалось, что acm* -функции начинают вываливать добавочную информацию в стек, убивая там что не попадя. Вообщем переделал это дело под С++:
Код: plaintext
1.
2.
3.
struct my_WAVEFORMATEX : public WAVEFORMATEX {
	BYTE Ext[ 1024 ];
};

В итоге, я сейчас остановился на следующем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
	Format.wFormatTag=type_win; 

	if (acmFormatEnum ( 
		NULL,
		&Details,
		fmtCb,
		MY_FMT_ENUM_INSTANCE, 
  	    ACM_FORMATENUMF_WFORMATTAG
	)) return - 21 ;
где type_win - тип формата в формате mmreg.h

В результате каллбак мне вываливает идентификаторы драйвера с форматоми этого типа. Так складывается, что если задовать PCM, то вываливается драйвер, который может конвертить внутри типа PCM, если указать другой тип, то вываливается драйвер, который может конвертить только между типами. Причем по одному для ALAW, MULAU, ADPCM (интересно, почему). Вообщем, думаю действовать так:

Допустим задан файл PCM
1. Конверчу его чем попало в похожий формат на требуемый.
2. Находу драйвер, который мне выволит acmFormatEnumCallBack и попытаюсь им конвертнуть в тип формата, который мне нужен.

Других путей я не вижу. Будет ли это лучше, чем acmFormatSuggest()?

И возникает подводный камень, который, надеюсь пройдет на ура. PCM в 4-х битах не существует, а ADPM, как я понял, только в 4-х битах и бывает. Остается надеятся, что ADPM-й драйвер свправиться с этой задачей
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33698308
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин, все равно не хочет...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
	if (end_conv && drvInfo_n) {
		if (acmDriverOpen(&phad, drvInfo[ 0 ].drvID,  0 )) return - 24 ;
	}

	if (end_conv) {
		if (ret=acmFormatSuggest(drvInfo_n ? phad : NULL, &wfxSrc, &wfxDst, sizeof (wfxDst)+CONVERT_EXT_BUFFER, 
									ACM_FORMATSUGGESTF_WFORMATTAG
									| ACM_FORMATSUGGESTF_NSAMPLESPERSEC
									| ACM_FORMATSUGGESTF_NCHANNELS 
									| ACM_FORMATSUGGESTF_WBITSPERSAMPLE
		)) {
			switch (ret) {
				case MMSYSERR_INVALFLAG: return - 25 ;
				case MMSYSERR_INVALHANDLE: return - 26 ;
				case MMSYSERR_INVALPARAM: return - 27 ;
				case ACMERR_NOTPOSSIBLE: return - 28 ;
				default: return - 29 ;
			}
		}
	} else {

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
-	wfxSrc	{...}
-	tWAVEFORMATEX	{...}
	wFormatTag	 1 
	nChannels	 1 
	nSamplesPerSec	 8000 
	nAvgBytesPerSec	 8000 
	nBlockAlign	 1 
	wBitsPerSample	 8 
	cbSize	 0 
+	Ext	0x0012ef5e ""
-	wfxDst	{...}
-	tWAVEFORMATEX	{...}
	wFormatTag	 6 
	nChannels	 1 
	nSamplesPerSec	 8000 
	nAvgBytesPerSec	 3435973836 
	nBlockAlign	 52428 
	wBitsPerSample	 8 
	cbSize	 0 
+	Ext	0x0012eb4a ""



Код: plaintext
1.
+	phad	0x00138b30
...
Рейтинг: 0 / 0
Не понятно как шагать...
    #33706762
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разобался. Например, при конвертировании из PCM в другие форматы надо иметь запас по битам, например в ALAW 8 надо иметь PCM 16
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Не понятно как шагать...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]